---
# System prepended metadata

title: Triage meeting 2024-07-17
tags: [triage-meeting, T-lang, minutes]

---

---
title: Triage meeting 2024-07-17
tags: ["T-lang", "triage-meeting", "minutes"]
date: 2024-07-17
discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202024-07-17
url: https://hackmd.io/KeYMqsVyQ2mMYGLpqVnF4Q
---

# T-lang meeting agenda

- Meeting date: 2024-07-17

## Attendance

- People: TC, ⅓scottmcm, Josh, nikomatsakis, Daria Sukhonina, Eric Holk, Xiang, CE, Urgau, Santiago, ½tmandry

## Meeting roles

- Minutes, driver: TC

## Scheduled meetings

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

Daria: Tracking progress on "Initial support for auto traits with default bounds" rust#120706

### 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

### Retrospectives

TC: We have three retrospectives queued up now:

- Unsafe attributes: How we managed to block this long enough to put it in edition jeopardy when RalfJ started in plenty of time.
- Precise capturing RFC/stabilization: We've been working on this a long time, and working on it in a focused way, and yet we managed to surprise people with it, creating some consternation.
- [RFC 3373](https://rust-lang.github.io/rfcs/3373-avoid-nonlocal-definitions-in-fns.html): We pared back this RFC to match our consensus, but by accepting the RFC which had broader aims, people read into this those broader aims and tried to make that happen.  When we reaffirmed our actual consensus, people were confused and had wasted a bunch of time.
  - Josh: Our communication of this didn't come across as including rationale, and we likely broke "no new rationale" a few times.

Perhaps we should talk about how we want to approach these in the planning meeting.

### Lang project goal slate

TC: The project goals RFC is up, and there's a slate of items for lang.  We should look over these:

https://github.com/nikomatsakis/rfcs/blob/project-goals-2024h2/text/0000-Project-Goals-2024h2.md#lang-team

Our checkboxes are here:

https://github.com/rust-lang/rfcs/pull/3672#issuecomment-2221533061

## 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

### "Stabilize opaque type precise capturing (RFC 3617)" rust#127672

**Link:** https://github.com/rust-lang/rust/pull/127672

In RFC 3498, we adopted the Lifetime Capture Rules 2024.  These will cause us to, by default, capture all lifetimes in RPIT-like impl Trait opaque types in the new edition.

```rust
//@ edition: 2024

fn captures(x: &()) -> impl Sized {}
//                     ~~~~~~~~~~
//                   Now captures `'_`.
//
//          ...or, "look ma, no `+ '_` needed!"
```

Since those lifetimes are not captured today, we need a semantics-preserving way to migrate code.

In RFC 3617, we adopted *precise capturing* as the way to do this.  We later amended the syntax for it by FCP in #125836.  Combined, it lets us write:

```rust
fn does_not_capture(x: &()) -> impl Sized + use<> {}
//                             ~~~~~~~~~~~~~~~~~~
//                    Does not capture the elided lifetime.
```

We now propose this for stabilization.  This syntax needs to be stabilized in all editions ahead of Rust 2024.

It helps us on the edition side to stabilize this sooner rather than later.  We test the migrations to Rust 2024 using crater, and we're not equipped to properly do this for the new capture rules until this syntax is stable.  Until it's stable, the documentation can't get merged to the Reference, and people can't use the edition guide to migrate their code ahead of the edition.  Etc.  We don't want things to build up at the end, so we want to cross this (and other items) off as soon as they are ready.

This stabilization is *partial*.  We're stabilizing just the highest confidence parts that are needed for edition migration.  There are two main restrictions:

1. All type and const parameters in scope must be included in the `use<..>`.
2. The syntax can't be used in trait definitions.

We foreshadowed these kind of restrictions in the RFC when we discussed the stabilization strategy.

This feature was implemented by CE and landed in nightly, ahead of the RFC being posted, in April.

In terms of secondary tooling, we've merged support for this to `rustfmt` and to `rustdoc`.  We have open issues for `rust-analyzer` and an open PR for `syn`.  The r-a team has responded that the needed change is easy, and someone has volunteered to do it.

We're converting `rustc` to use the new syntax itself rather than the `Captures` trick.  I've seen a draft commit for this.

I've also reached out to the RfL team to see whether they might be able to switch over to this soon.

Looking at a calendar, the soonest this could stabilize is with Rust 1.82 which branches on 2024-08-30 and will be released on 2024-10-17.  That's also the date that we'll be announcing the Rust 2024 nightly beta.

Jack Huey has asked us to file a concern for him once we start FCP.  Though he "quite like[s] this feature and where it ended up in terms of how you specify the captured parameters," and believes that"overall, having this feature will make the language better," he also "has very strong doubts that we as language developers have properly done our due diligence here to ensure that language users understand this feature, how to use it, and that it all-in-all brings down the net burden of learning Rust."

I've asked Jack if he could clarify what he'd want to see concretely to resolve that concern, and Niko has made a specific proposal to Jack that includes the retrospective we have planned.

TC: That's the situation.  What do we think?

NM: I've started on a blog post here but didn't get far.

TC: We can collaborate on that.

NM: I think people may be missing the big picture here, in terms of the changes to captures and `impl Trait`.

NM: Apart from that, I'd like to see us move forward.  I don't see a reason to slow peddle this here.

NM: I'll propose FCP and file the concern.

### "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?

### "regression: let-else syntax restriction (right curly brace not allowed)" rust#121608

**Link:** https://github.com/rust-lang/rust/issues/121608

TC: We decided on a breaking grammar change.  At the time we did this, there was no crater breakage.  25 hours later, someone added some code to GitHub in one non-`crates.io` crate that breaks.  In a meeting on 2024-03-06, we decided to do it anyway.  We followed up with an FCP, but it's been hanging out, so Josh nominates for us.

TC: Easy checkboxes probably.

### "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.

The RFC does 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;
}
```

We proposed FCP merge awhile back, but it has an open concern.

TC: What can we do to move this forward?

Josh: Other than the `async Fn` concern I raised, the rest of the RFC looks great and I think we should move this forward. Proposed syntax: `AsyncFnMut(Args) -> T`.

NM: I personally like the `async Fn()` syntax.  I do think that this is signaling a particular direction. I kinda like that direction.

scottmcm: This is less precedent setting than it would be in other places due to the paren syntax.

TC: Agreed the paren syntax is the key here to this being more minimal than it otherwise would be.  It's worth noting there are things we could do in `rustdoc` to make this first-class.

NM: It seems we have more to do to reach alignment.

TC: We'll schedule a special design meeting for 1630 UTC on Monday then, that's 9:30 PDT, and 12:30 EDT.  That's the 22nd.

### "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?

TC: I'm +1 also on this.

Josh: This seems like a reasonable restriction.

scotttmcm: I'm wondering whether we can cut this down further actually to just blocks, i.e. braces, except for where we've already stabilized this, e.g. closures.  E.g., for `if {} else {}`, it could be ambiguous if placed before the `if` if it covers the `else`.

scottmcm: I'll make a proposal and propose FCP.

### "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.

Josh: I'd be happy to charter this as an experiment.  I'd like to see some document describing what the outcome would look like.

tmandry: I'd be happy to second an experiment.

NM: I'm also in favor of experiments here.  I'm not sure I support it (unforgettable types) as a feature of the language, but I want to discuss it.

Daria: Here's my text about unforgettable types:

https://zetanumbers.github.io/book/myosotis.html

scottmcm: Happy to see an experiment here.  But I want to note the standing skepticism on additional `?` trait bounds.

*Consensus*: Experiment approved; tmandry to follow up.

(The meeting ended here.)

---

### "Stabilize `raw_ref_op` (RFC 2582)" rust#127679

**Link:** https://github.com/rust-lang/rust/pull/127679

TC: RalfJ proposes that we stabilize `raw_ref_op`:

```rust
#![feature(raw_ref_op)]

use core::mem::MaybeUninit;

fn main() {
    let mut x: MaybeUninit<u8> = MaybeUninit::uninit();
    let _y: *const _ = &raw const x;
    let _z: *mut _ = &raw mut x;
}
```

This is the syntax for the feature that currently underlies `addr_of!` and `addr_of_mut!`.

This feature and syntax comes from RFC 2582:

- https://github.com/rust-lang/rfcs/pull/2582

Ralf argues, in brief:

- It's clear these are here to stay; it's time to give a proper syntax.
- Giving these syntax will help with understanding among users.
- The `addr_of` name is unfortunate, given provenance, and this would help in getting rid of that.

There was extensive litigation of the syntax on the RFC.  The obvious choice was `*const $place` and `*mut $place`, but people didn't like the `*` being there as it usually means dereference.  So we landed on `&raw const $place` and `&raw mut place`.

There's been discussion of using `&raw $place` instead for const pointers, but this requires an edition so as to reserve `raw` as a contextual keyword.  This would also rule out later using `&raw $place` for one of the improved pointer types that people have discussed.

Otherwise, semantically, these work exactly like the macros, so there don't seem to be a lot of truly open questions here.

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.

### "Tracking issue for the `quote!` macro in `proc_macro`" rust#54722

**Link:** https://github.com/rust-lang/rust/issues/54722

TC: In our discussion about adding syntax for getting the tag (or discriminant?) from an enum variant, it was brought up that `#foo`-style syntaxes could be a problem for the `quote` crate, but that perhaps this would be less of a problem if we stabilized [proc_macro::quote](https://doc.rust-lang.org/proc_macro/macro.quote.html) (since it uses `$` instead for unquoting).

This stabilization has been languishing for the last... five and a half years.  I'm not sure whether this falls more on us or on `libs-api` (it's tagged for both).  Either way, it seems worth discussing whether this is something we want to see happen and whether anything is blocking it.

TC: What do we think?

### "PinCoerceUnsized trait into core" rust#125048

**Link:** https://github.com/rust-lang/rust/pull/125048

TC: In the discussions of RFC 3621 for `#[derive(SmartPointer)]`, apparently one particular unsoundness was noted.

Ding now proposes `PinCoerceUntsized` be added to `core` to address this.  He's asked for our review.

TC: What do we think?

### "size_of_val_raw: for length 0 this is safe to call" rust#126152

**Link:** https://github.com/rust-lang/rust/pull/126152

TC: RalfJ nominates this to give us a chance to intervene in an opsem FCP to change the documentation for the unstable [`size_of_val_raw`](https://doc.rust-lang.org/nightly/std/mem/fn.size_of_val_raw.html).

It's about adding a special case for making the function always safe to call when the dynamic tail length is zero.

TC: What do we think, do we want to intervene?

### "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?

### "Importing an enum variant can create a conflict with a new prelude type" rust#127738

**Link:** https://github.com/rust-lang/rust/issues/127738

TC: Josh nominates for us:

> The experiment in #125107 uncovered an interesting source of version breakage, which occurs if the standard library prelude attempts to introduce an additional type.
>
> Suppose `std` adds the type `Cell` to the prelude. This will break code that looks like this:
>
```rust
use Cell::A;
//~^ ERROR `Cell` is ambiguous

// The derive here is important but it doesn't particularly matter which trait is being derived.
#[derive(PartialEq)]
pub enum Cell {
    A
}
```
>
> This makes it a _potentially_ breaking change to add new types to the prelude. We could still potentially add types that create no actual breakage (e.g. because no extant Rust code declares its own conflicting type), but this nonetheless introduces a potential source of breakage that could block introducing new types until an edition boundary (and creates one more thing people have to deal with when migrating to the new edition).
>
> It seems worth exploring whether we can, or should, attempt to fix this, such as by allowing the type to shadow in this case. Note that it _does_ properly shadow if there's no `derive` on the enum.
>
> Nominating for lang discussion on the "should we" question: should we consider doing something to eliminate or mitigate this source of conflict? This kind of conflict applies both to the current problem with the standard library prelude, as well as any potential future features for letting other libraries have preludes.

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?

### "Fixup Windows verbatim paths when used with the `include!` macro" rust#125205

**Link:** https://github.com/rust-lang/rust/pull/125205

TC: Chris Denton asks us:

> On Windows, the following code can fail if the `OUT_DIR` environment variable is a [verbatim path](https://doc.rust-lang.org/std/path/enum.Prefix.html) (i.e. begins with `\\?\`):
>
> ```rust
> include!(concat!(env!("OUT_DIR"), "/src/repro.rs"));
> ```
>
> This is because verbatim paths treat `/` literally, as if it were just another character in the file name.
>
> The good news is that the standard library already has code to fix this. We can simply use `components` to normalize the path so it works as intended.
>
> I think it could just be considered a bug fix but it might also be considered a change in language.

TC: What do we think, is this a bug fix or a change to the language, and if the latter, do we want it?

### "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?

### "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?

### "Implement lint against ambiguous negative literals" rust#121364

**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?

### "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?

### "[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.

### "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.

### "RFC: inherent trait implementation" rfcs#2375

**Link:** https://github.com/rust-lang/rfcs/pull/2375

### "Add support for `use Trait::func`" rfcs#3591

**Link:** https://github.com/rust-lang/rfcs/pull/3591

## 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

None.

## `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

### "`repr(tag = ...)` for type aliases" rfcs#3659

**Link:** https://github.com/rust-lang/rfcs/pull/3659

### "Fixup Windows verbatim paths when used with the `include!` macro" rust#125205

**Link:** https://github.com/rust-lang/rust/pull/125205

### "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

## Proposed FCPs

**Check your boxes!**

### "regression: let-else syntax restriction (right curly brace not allowed)" rust#121608

**Link:** https://github.com/rust-lang/rust/issues/121608

### "Async closures" rfcs#3668

**Link:** https://github.com/rust-lang/rfcs/pull/3668

### "Guard Patterns" rfcs#3637

**Link:** https://github.com/rust-lang/rfcs/pull/3637

### "`repr(tag = ...)` for type aliases" rfcs#3659

**Link:** https://github.com/rust-lang/rfcs/pull/3659

### "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

## Active FCPs

### "Reorder trait bound modifiers *after* `for<...>` binder in trait bounds" rust#127054

**Link:** https://github.com/rust-lang/rust/pull/127054

### "size_of_val_raw: for length 0 this is safe to call" rust#126152

**Link:** https://github.com/rust-lang/rust/pull/126152

### "Implement lint against ambiguous negative literals" rust#121364

**Link:** https://github.com/rust-lang/rust/pull/121364

## P-critical issues

None.
