---
# System prepended metadata

title: Planning meeting 2024-04-03
tags: [T-lang, minutes, planning-meeting]

---

---
title: Planning meeting 2024-04-03
tags: ["T-lang", "planning-meeting", "minutes"]
date: 2024-04-03
discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Planning.20meeting.202024-04-03
url: https://hackmd.io/c_-Fm49QRASsH7m-0VmtZw
---

# T-lang planning meeting agenda

- Meeting date: 2024-04-03

## Attendance

- People: TC, waffle, eholk, tmandry, Josh, Nadri, NM, pnkfelix, scottmcm, Mara

## Meeting roles

- Minutes, driver: TC

## Proposed meetings

- "Design meeting: Precise capturing" [#261](https://github.com/rust-lang/lang-team/issues/261)
- "Design meeting: Deref Patterns" [#260](https://github.com/rust-lang/lang-team/issues/260)
- "Design meeting: async closures" [#262](https://github.com/rust-lang/lang-team/issues/262)
- "Design meeting: New Range types for Rust 2024" [#259](https://github.com/rust-lang/lang-team/issues/259)
- "We need to settle the behaviour of floating-point in `const`" [#222](https://github.com/rust-lang/lang-team/issues/222)
- "Design meeting: Profiles" [#245](https://github.com/rust-lang/lang-team/issues/245)
- "Nail down cargo-script syntax proposal" [#232](https://github.com/rust-lang/lang-team/issues/232)
- "discuss/resolve `fn { mod { (use) super::...; } }` and its interaction with derive patterns" [#193](https://github.com/rust-lang/lang-team/issues/193)
- "Design meeting: Rust issues encountered by new Rust users in the Bevy project" [#229](https://github.com/rust-lang/lang-team/issues/229)

Please update these in https://github.com/orgs/rust-lang/projects/31/views/7.

## Availability

scottmcm: I think I'm available this month.

- 10th: Edition review.
  - pnkfelix: Unavailable.
  - tmandry: I'm a question mark on this date.
- 17th
  - Josh: I'm a question mark on this date.
  - nikomatsakis: Unavailable.
- 24th: Precise capturing.

## Project goals

NM: I'd like to talk about project goals.

Josh: +1.  I'm happy to help put something together.

NM: I'd like to talk about the specific goals rather than the mechanism.

NM: I'd like to put out a public announcement and call for proposals on this to try to find owners.

- [Slides](https://nikomatsakis.github.io/team-goals-2024/)
- [Proposal to Leadership Council](https://hackmd.io/@nikomatsakis/ByFkzn_10)

*Consensus*: We'll schedule a special meeting for this:

https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Planning.20meeting.202024-04-03/near/431137683

## async closures

TC: CE and I have been discussing this.  He's interested in talking this over with the team.

NM/tmandry: We should talk about this.  Maybe in May.

## New Range types

NM: Is this going to happen?

scottmcm: Could we just add the types and not language bits until Rust 2027?

Mara: What we still need is guidance for the library authors about what to do.

Mara: We cannot add a type if we cannot explain to the world how to use this.

Mara: We might want to discuss delaying the edition.  Maybe we should have a Rust 2025 edition.

scottmcm: It'd be good for us to aggressively go through and punt things from the edition.  (Delaying the edition for things will make 2027 also be a rush; if people know things get punted out it'll make it more likely they'll actually happen the year before next time.)

*Consensus*: We'll do edition review on the 10th.

## Precise capturing

### Background

TC: We accepted the RFC and the implementation has landed for Rust 2024.  We do need to stabilize some way of expressing precise capturing.  We're close to stabilizing ATPIT.

TC: However, in terms of timeline, landing TAIT is going to be tight (to the point of likely impossible).  I'm going to write an RFC with a more direct means for precise capturing, e.g. using `impl<'t, T> Trait` or `impl('t, T) Trait` syntax.  E.g.:

`-> impl<'t, T> Trait'`

`-> impl<> Trait`

We should discuss this as this work will need to start immediately to make the edition.

NM:

`-> impl[] Trait` -- technically unambiguous, I suppose :) (`[T]` is not a trait)

```rust
fn foo<T>(&self, data: &Vec[T]) -> impl<T> Trait { ... }
```

(Discussion about "why can't we land TAIT ahead of the edition?")

TC: Landing TAIT in time is just going to be too tight and too much of a rush.  No-one wants TAIT to land sooner than I do, and I'm still saying this, so that might be one reference point.  It makes a lot of sense to land ATPIT first and to let that soak for 2-3 releases.  The design axioms on which ATPIT were based were *great* (thanks NM) and led to a simpler and better design.  There may well be lessons from those that we should carry over into the design of TAIT, but none of us are thinking hard about those at the moment because we're still trying to land ATPIT.

TC: The ATPIT stabilization is going well, but there are just a lot of little thingss to do, and we're waiting, e.g. on FCP periods to complete on the T-types side to solve various blockers.  Even landing ATPIT ahead of Rust 2024 may be tight.

NM: I'm amenable to the idea of doubling down on ATPIT and doing this, then we can do TAIT in 2025.

TC: In talking with Oli, the feeling is that we need to start on this soon, as even landing this syntax will be tight before Rust 2024 when considering the lead time of the implementation, the various reviews, and the time for various FCPs on the types side.

NM: Timeline:

- Bikeshed.
- Implementation.
- Stabilization.

NM: It seems to me that the role of lang + types is fairly clear:

- lang -- What is the syntax?
- types -- Given some list of type parameters derived in some way from the syntax, implement an opaque type that captures just those generics.

Can we then proceed with an experiment + bikeshed in parallel? It may also be useful to stabilize or pursue an impl that only supports the case where all type parameters are specified (since the compiler impl already has to deal with that).

TC: In terms of the semantics, for reference (and for why we don't want people to have to write this by hand), here's a desugaring prepared for the RFC:

```rust
// This is an example of how precise capturing syntax could be
// desugared to ATPIT.

#![feature(impl_trait_in_assoc_type)]
#![allow(unused)]

struct Ty<'u, U>(&'u (), U);

impl<'u, U> Ty<'u, U> {
    // Equivalent to `-> impl<'u, 't, U, T> Sized`.
    pub fn f<'t, T>(self, x: &'t (), y: T) -> <() as _0::H>::Opaque<'u, 't, U, T> {
        <() as _0::H>::f(self, x, y)
    }
}

mod _0 {
    use super::*;
    pub trait H {
        type Opaque<'u, 't, U, T>;
        fn f<'u, 't, U, T>(s: Ty<'u, U>, x: &'t (), y: T) -> Self::Opaque<'u, 't, U, T>;
    }
    impl H for () {
        type Opaque<'u, 't, U, T> = impl Sized;
        #[inline(always)]
        fn f<'u, 't, U, T>(s: Ty<'u, U>, x: &'t (), y: T) -> Self::Opaque<'u, 't, U, T> {
            (s, x, y)
        }
    }
}

fn main() {
    let _ = Ty(&(), ()).f(&(), ());
}
```

Waffle: +1 on that plan.

NM: Also, this allows a much more straightforward migration than with TAIT.

Josh: Even if we could ship TAIT in two weeks, this is still something that we might want and that has value.

NM: +1.  The bet before was that "maybe we'll want this, but maybe we could get away with just TAIT".  So in many ways I feel good about just doing it.

tmandry: +1.  Maybe we should just start the bikeshed now.

TC: +1.  The main point of bikeshed is what character to use.

### Bikeshed part 1

tmandry: My only concern on the angle bracket is that for `impl` it's normally used to introduce a parameter.

Waffle: Angle brackets are used for introducing parameters and applying them to items.  So it's not completely new for Rust.  I see how it could be confusing, but I think it'd be fine.

NM: It's a really nice syntax.  I almost hate to use it here, which I think will be obscure.  I would prefer `impl<'a>` being used to mean `impl for<'a>`.  So I have mixed feelings.

Nadri: If we had an explicit syntax for closure capture we could reuse it for type/lifetime capture.

tmandry: Of the options on the table... mixed feelings.

Josh: My feeling is that trying to use `impl<'a>` as an alias for `for<'a>` I think would be more confusing.

Josh: More broadly, I think this is actually consistent with our use of angle brackets and `impl`.

tmandry: There is a sense in which it is consistent, but it depends where you put the weight.

pnkfelix: Maybe `move(...) impl Trait` would actually make sense.  (As in `move('a, T) impl Trait`... since you're allowing the lifetime and type to propogate ("move") into the existentials.

NM: Relevant, my prior "explicit capture clause" for closure proposal: https://hackmd.io/@nikomatsakis/SyI0eMFXO, which was using `move(a) || ` as the syntax.

NM: +1 to Nadri's point; it'd be nice if we could share syntax for this.

Nadri: The `forall` understanding doesn't *quite* work because we can't add bounds like `-> impl<T: Clone> Trait`.

NM: That's hopefully a temporary limitation.

Josh: Is there a `+ 'a` style syntax we could use.

NM: It means the wrong thing, something more like union than intersection.

TC: We could generalize the notion Josh is proposing here and have, e.g., additional syntax in the bound.  E.g. `impl Trait & 'a & T` or whatever to capture the notion of intersection rather than union (though these options seem bad in other ways, e.g. that we need a way to express "captures nothing" and this doesn't naturally provide that).

TC: +1 on sympathy to wanting a shared syntax for closure capturing.

pnkfelix: I don't hate using the `use` keyword.

pnkfelix: If we use a new keyword, we may have more freedom about where it can be placed.

tmandry: While I'm mildly worried about the ambiguity, this isn't decisive for me.

As an idea, this could mean to capture everything, i.e. another way to express the default:

```rust
-> impl<..> Trait
-> impl<_> Trait
```

### Consensus on the feature modulo syntax

TC: Subject to us resolving this bikeshed, are we all +1 on this?  That is, we're in favor of adding some syntax to solve this problem; we just need to work out what that syntax is exactly.

NM, tmandry, Josh, scottmcm, pnkfelix, TC: +1.

*Consensus*: Subject to resolving the bikeshed, we're all in favor of adding syntax for this purpose.

### Bikeshed part 2

TC: Back to the bikeshed, let's write out all the options:

```rust
-> impl<'t, T> Trait // 
-> impl('t, T) Trait // 
-> impl['t, T] Trait // 
-> impl Trait & 't & T // 
-> impl use<'t, T> Trait // 
-> impl captures<'t, T> Trait // 
-> impl move<'t, T> Trait // 
```

scottmcm: given Niko's earlier statement about letting `impl<'a>` being `impl for<'a>` potentially, my favourite (weakly) is something with a (probably contextual) keyword to be more specific about it being a capture list.

NM: Consider, e.g., these cases.  The key point here is that it does NOT capture `'_`:

```rust
fn foo<T>(&self, vec: Vec<T>) -> impl use<T> Display
fn foo<T>(&self, vec: Vec<T>) -> impl Display & T

fn foo<T>(&self, vec: Vec<T>) -> impl use<> Display
fn foo<T>(&self, vec: Vec<T>) -> impl Display & [] ?
```

pnkfelix: `Trait & ['a, T]` would be clearer than `Trait & 'a & T`, (not that I like either of those).

scottmcm: `AsRef &T` and `AsRef<&T>` being different feels really awkward.

tmandry: Can we "opt out" from a capture list? e.g. `-X` to mean "doesn't capture X".

TC: I would expect to have a positive and negative form, so you can say `impl<.., -X>` or something like that.  But we could do that later, and we've never gotten around to doing this for imports with `use` though there is a similar use case there.

TC: Let's survey our preferences:

| Person         | `<>` | `()` | `[]` | `&` | `use<>` | `captures<>` | `move<>` | `via<>` |
| ------         | ---- | ---- | ---- | --- | ------- | ------------ | -------- | ----     |
| nikomatsakis   | -1*  | -1*  | -1*   | -1  | +1 ish  | -0           | +0.5     | -0      |
| joshtriplett   | +1   | -1   | -0.5 | -1  | +0.5    | +0.9         | -1       |
| pnkfelix       | +0.1 | +0.5 | +0   | -1  | +1      | +1           | +1       |
| tmandry        | +0.75| -0   | +0.5 | -1  | +0.75   | +0.75        | -1       | +0.5 |
| TC             | +0.5   | +0   | -0   | -1  | +1      | +0           | -0       | +0 |
| waffle         | +1   | +0   | -1   | -1  | -1      | -1           | -1       |

NM: The problem with `captures` is that it's just too long.  I want to use it on closure captures also, and it's just too long.

Josh: Aside from closure captures, how do you feel about it?

NM: I'll go `-0` maybe.  I like the clarity, but it just doesn't feel like Rust.

pnkfelix: Regarding the length complaint against "captures", perhaps`impl via<'a, T>`?

tmandry: Brainstorming about closure captures syntax:

```rust!
let foo = String::from("hello");
let mut v = vec![];

let fun = move(foo.clone()) || { ... };
let fun = use(foo.clone()) || { ... };
let fun = captures(foo.clone()) || { ... };
```

TC: For closures there are the values that we capture, but there's also the capturing of the outer type and lifetime parameters.  We often don't want to capture all of those.  This comes up also for `async` blocks, and it will come up for `gen`, `async gen`, async closures, `gen` closures, `async gen` closures, etc. also.

NM: moving to -1 on `<>` because of TC's point that we may want to limit type capture for closures, async blocks, async generators, genreators, etc. etc. etc. and I don't see how the `<>` syntax will scale to that. (On same point, not sure it will always want to be contextual.)

TC: This has been helpful.  It seems that if possible we want something that aligns with what we might want to do for closure-like blocks.  I'll write something up.  We'll try to get an experiment going in parallel.

(The meeting ended here.)

---

## Active initiatives

### "project-safe-transmute" lang-team#21

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

### "const-evaluation" lang-team#22

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

### "const-generics" lang-team#51

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

### "Deref patterns" lang-team#88

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

### "Generators (iterator functions), sync and async" lang-team#137

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

### "Initiative: trusted external static declarations" lang-team#149

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

## Pending proposals on the lang-team repo

None.

## Pending PRs on the lang-team repo

### "Proposal: Remove `i128`/`u128` from the `improper_ctypes` lint" lang-team#255

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

### "Lang discussion: Item-level `const {}` blocks, and `const { assert!(...) }`" lang-team#251

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

### "project-safe-transmute" lang-team#21

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

### "const-evaluation" lang-team#22

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

### "clarify lint policy " lang-team#48

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

### "const-generics" lang-team#51

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

### "Make a place for a "lang team wishlist"" lang-team#54

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

### "Link in design meeting template is dead" lang-team#80

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

### "Eventual Concern: Send/Sync insufficient in the presence of multiple execution contexts." lang-team#87

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

### "Deref patterns" lang-team#88

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

### "Specification of safe rust ?" lang-team#123

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

### "Generators (iterator functions), sync and async" lang-team#137

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

### "Initiative: trusted external static declarations" lang-team#149

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

### "agenda generation should include section with S-waiting-on-team + T-lang" lang-team#172

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

### "dead Zulip/zulip-archive links" lang-team#185

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

### "HTTP Error 404 in the Chat Platform p link" lang-team#186

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

### "discuss/resolve `fn { mod { (use) super::...; } }` and its interaction with derive patterns" lang-team#193

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

### "lang agenda generator ignores lang-nominated closed issues" lang-team#199

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

### "mdbook build and deploy is failing" lang-team#221

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

### "We need to settle the behaviour of floating-point in `const`" lang-team#222

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

### "Design meeting: Rust issues encountered by new Rust users in the Bevy project" lang-team#229

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

### "Nail down cargo-script syntax proposal" lang-team#232

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

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

### "Lang-team RFC guidelines appear to be out of date" lang-team#244

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

### "Design meeting: Profiles" lang-team#245

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

### "Update hackmd link to a public link" lang-team#258

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

### "Design meeting: New Range types for Rust 2024" lang-team#259

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

### "Design meeting: Deref Patterns" lang-team#260

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