---
# System prepended metadata

title: Planning meeting 2023-12-06
tags: [T-lang, minutes, planning-meeting]

---

---
title: "Planning meeting 2023-12-06"
tags: ["T-lang", "planning-meeting", "minutes"]
date: 2023-12-06
discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Planning.20meeting.202023-12-06
url: https://hackmd.io/jNCHJnQrQGiXwVPAmmdYCg
---

# T-lang planning meeting agenda

- Meeting date: 2023-12-06

## Attendance

- People: TC, tmandry, eholk, waffle, Josh, scottmcm, eholk

## Meeting roles

- Minutes, driver: TC

## Availabiliy

- December 13: Everyone present is available.
    - Let's do match ergonomics.
- December 20: Everyone present is available.
    - Let's do lang-team#235.
- December 27: rule out due to holiday
    - Between Christmas and New Years.
    - Let's cancel.

## Proposed meetings

- "We need to settle the behaviour of floating-point in `const`" [#222](https://github.com/rust-lang/lang-team/issues/222)
- "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)
- "Design meeting: resolve ABI issues around target-feature" [#235](https://github.com/rust-lang/lang-team/issues/235)
- "Nail down cargo-script syntax proposal" [#232](https://github.com/rust-lang/lang-team/issues/232)
    - Might be able to settle this in a triage meeting, depending on async discussion and proposal updates.

Other pending proposals include:

- Standing proposal: Work on the 2024 edition.
- Discussing the needs and use cases of Rust for Linux.
    - Trevor Gross mentioned he's writing something up for this and asked to be kept in mind.
    - He's now proposed a design meeting (posted during this meeting): https://github.com/rust-lang/lang-team/issues/240
- Flexible Unsize and CoerceUnsize traits - [pre-RFC](https://internals.rust-lang.org/t/pre-rfc-flexible-unsize-and-coerceunsize-traits/18789).
- Improvements to match ergonomics - [proposal in issue](https://github.com/rust-lang/rust/issues/64586#issuecomment-1837919844).
    - Seems like we wouldn't get through this in a triage meeting, might want to use a design meeting for it.
- P-high lang issue, incorrect UB when when a ! place is constructed (but not loaded!) [#117288](https://github.com/rust-lang/rust/issues/117288)

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

## Discussion

tmandry: We should schedule Rust for Linux if there will be a doc for it.  Not clear whether that would happen yet or not.

Josh: Could also follow through with inviting someone from Bevy to talk about their list of issues new users encounter.

TC: The lang-team#235 has a doc ready from RalfJ.

tmandry: Making a short list, lang-team#235 should probably be discussed.  Also RFL.

tmandry: Looking at the match ergonomics, some of those are edition-related, so we should prioritize.

tmandry: I'd propose we schedule that and the doc that RalfJ prepared.  And we should tell the RFL folks that we definitely want to talk about that.

TC: Thoughts?  Hearing none, sounds like consensus.

TC: Propose the match ergonomics first, as it's edition sensitive, then RalfJ's the week after.

## Planning for 2024 edition

Project board: https://github.com/orgs/rust-lang/projects/43

### Disallow *references* to static mut [Edition Idea] - #114447

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

TC: I'm meaning to write an RFC about this.

tmandry: One question is do we need one.

scottmcm: I'd probably hope for an RFC here, but hopefully a short one.  (It's something that people have been using in stable for a while, so it feels like "more" than just an issue, in a sense.)

Josh: We may want a `&raw` syntax, so there could be churn here. Not a blocker, since we could suggest one thing, then later suggest another, just a consideration.

scottmcm: We really just want people to use `SyncUnsafeCell` or to define their own type.

Josh: Should we reopen the discussion of forbidding `static mut`?

scottmcm: Yes, but not for the 2024 edition.

scottmcm: I like RalfJ's suggestion here.  We can discourage `static mut`, but in the meantime to maybe later removing it, we can do this.

tmandry: Sounds like we want an RFC.  I'll unnominate this.

Josh: Note that `SyncUnsafeCell` only implements `Sync` if `T` implements `Sync`.  We may want an unsafe type that always implements `Sync`.

scottmcm: That's surprising, since `SyncUnsafeCell` was, I thought, designed for this use case.

### Fix whitespace escaping behavior in string literals

(No issue link.)

Some background:

https://github.com/rust-lang/reference/pull/1042

Josh: So in the edition, we'd remove the behavior of removing multiple newlines.

tmandry: There's also something about only skipping increments of 4.

Josh: We should fix this.

waffle: This is probably complicated enough to merit an RFC.

waffle: Do we want a special syntax for multiline strings, like what Zig does?

tmandry: Anyone disagree this needs an RFC?

Josh: It needs clear documentation at least.  I'd take it with a patch for the reference, or an RFC if others prefer that.

### "incorrect UB when when a `!` place is constructed (but not loaded!)" rust#117288

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

(TC: We deferred this from triage to maybe discuss in the planning meeting.)

TC: @RalfJ found some interesting examples where `rustc` generates SIGILL on code that shouldn't have UB.  T-compiler marked this P-high.  RalfJ:

> Nominating this to get first vibes on which of the following lines should be accepted, and which should be UB. (Currently they are all accepted and all UB but that's a bug.)
>
```rust
#![feature(never_type)]
fn deref_never<T>() {
    unsafe {
        let x = 3u8;
        let x: *const ! = &x as *const u8 as *const _;
        let _val = addr_of!(*x); // must be OK
        let _ = *x; // should probably be OK since we said `_` discards the place (and is UB-equivalent to `addr_of!`)
        let _: ! = *x; // does a no-op type annotation force the place to be loaded and hence cause UB?
        let _: () = *x; // is this UB? should we even accept such code?
        let _: String = *x; // what about this?
        let _: T = *x; // is this UB even if T = ! ?
    }
}
```

TC: I asked RalfJ for a proposal for the right behavior on the ones with question marks.  RalfJ:

> I don't know how to arrive at a principled answer to this. There's no obvious "correct" here, it's a judgment call.
>
> If you are asking for my personal preference ignoring backwards compatibility constraints, then my immediate gut feeling is that _places_ of type `!` should not be subject to never-to-any coercions (the coercion should apply only to _values_, matching the comment that justifies the coercion in the first place). So:
>
```rust
        let _: ! = *x; // OK, not UB
        let _: () = *x; // does not compile
        let _: String = *x; // does not compile
        let _: T = *x; // does not compile
```

TC: What do we think?

Josh: Why do we allow?:

```rust
let x: *const ! = &x as *const u8 as *const _;
```

scottmcm: You can create any pointer and it's inhabited.  The pointer is fine, but the read is invalid.

Josh: But that's not true at the type level.  Any time you have a never is code that will never be run.

scottmcm: If you have a byte that is `3`, and you can have a `*const bool` to it.  So the pointer is fine, but it's a pointer you can't read without invoking UB.  So that's entirely normal for raw pointers.

TC: +1 to scottmcm.

tmandry: +1 to scottmcm.

scottmcm: We can't even make a post-mono error, as it could be under an `if false`.  It's legal Rust code, just UB.

waffle: We shouldn't make these more special.  It'd be worth making them less special.

scottmcm: Consider tuples and partial initialization.

Josh: If you have a `*const (u32, !)`, can you dereference it if you only look at the `u32` and never create a `!`?

scottmcm: The question is, do we enforce validity rules on place creation or on place reading?

waffle: We really want to say that `let _ = *x` does not make a read.  We enforce validity when the place is converted to a value.  If you're not using the place in any way, then you don't hit the invalidity.

scottmcm: Consider:

```rust
let p: *const (u32, !) = ...;
let q = ptr::addr_of!((*p).0); // uses only *place* operations, not values
```

waffle: Yes I think this should be correct.

Josh: So if we accept any of the proposals for pointer projection, then this would be fine.

scottmcm: So this would be justifiable...

This should be legal even if U=! and f1 panics.

```rust
pub fn blah<T, U>(f0: impl Fn() -> T, f1: impl Fn() -> U) -> (T, U) {
    unsafe {
        let mut mu: MaybeUninit<(T, U)> = MaybeUninit::uninit();
        let p = mu.as_ptr_mut();
        //(*addr_of_mut!((*p))).0 = f0();
        // place projection here is fine, because it never became a value
        (*p).0 = f0();
        pointermagic.1 = f1();
        return mu.assume_init();
    }
}
```

waffle: An invalid type is OK in a place, but it's UB when you coerce that into a value.

scottmcm: The code above is the same as the original argument that these tuples can't be ZSTs because of what compiler does internally.  The compiler already wants to write code like this (at least to LLVM) for tuple creation.

waffle:

```rust
// Ralf's suggestion from above

// x: *const !

// OK because we say that `_` does not covert a
// place to a value.
let _: ! = *x; // OK, not UB

// This should not compile because if it compiled,
// it would make it so that we converted never to unit,
// and that would be immediate UB.
let _: () = *x; // does not compile
// because this is actually
let _: () = (*x) as ();
// and thus there's a value,
// and thus we don't *want* it to compile because that'd be super confusing

// Q: is this also doing a coercion
// in a world where it hits type fallback instead
// of inferring to `!`?  (Since nothing infers to `!` today)
// like if someone uses the never-type-on-stable hack...
//
// A: yes
let _ = *x; //~ Shouldn't compile because it infers unit and be UB, today.  But we want it to not compile.
// Today: compiles as UB because it infers as `()` due to fallback
// Wish: doesn't compile because oh god no.


let _: String = *x; // does not compile
let _: T = *x; // does not compile

enum Never {}
let y: *const Never = 1 as _; //~ OK today.

// this doesn't compile today,
// because there is no Never -> () place coercion which is probably incorrect with !
let _: () = *y; //~ ERROR: type mismatch

// This still will be UB:
let _: () = {*x};
```

Josh: No objection any longer about what was mentioned above.  Happy to defer to expert analysis here.

tmandry: Stabilizing `!` is one of the 2024 issues up for discussion.

TC: If there are things we could do in 2024 that would help make it possible to evetually do the never type, we should look at that.

scottmcm: If we stopped doing this coercion, and people had to write it out, that's one thing we could do.

scottmcm: second attempt at stabilizing never: https://github.com/rust-lang/rust/issues/57012

scottmcm: Nothing ever infers to `!` today because it's not a type on stable.  It's a weird magic syntax.  So reading a pointer to `!`, if you do a hack to get it, is that the value you get back will infer to unit, because that's what type parameter fallback does in these cases, which is why we're having trouble stabilizing never in the first place.  So because of that type parameter fallback, you get coercions in places that wouldn't be corecions for literally any other type.

waffle: That's correct.

waffle: Simple explanation:

```rust
// We want to say that this:
let _ = *x; //~ Does not do a read.
```

This implies that places don't enforce validity invariants.

Which means that a *place* coercion of `! -> T` is invalid, because it assumes that `!`'s validity invariant (false) was enforced.

I.e. The **place** coercion of `! -> T` (any type `T`) is a compiler *bug*.  It's wrong that we accept this code today.

If you have a value of never, then you can coerce it.  But you can't validly do that to a place.

TC: Does this have bearing on the never stabilization?

scottmcm: We can't remove the value coercion since we need that.  But if we could figure out how to remove the value coercion, that would make it more possible.

tmandry: We could change how the coercions work with the edition.  We could make it go from being implicit to explicit.

scottmcm: Of course, if it's explicit, it's not a coercion.

tmandry: It's a cast.

scottmcm: There's no place cast in stable Rust.  In this case, we'll get rid of the place coercion, so we don't need a place cast.

tmandry: Sounds good to me.  I trust you all to figure this out.

TC: Could we make those value coercions into casts, over an edition?

scottmcm: Maybe?  It's hard to make confident statements in this area.

scottmcm: If we could notice what you're calling is a function that returns `!` and treat that as control-flow rather than value flow somehow, and do that in a way that is edition dependent.  But this is all slightly wrong because of how we do HIR building.

scottmcm: Theoretically the only thing you can do with `!` today is to have a value return from a function.  It's technically wrong to use it elsewhere.  It's officially unstable, so maybe we could carve something out.

TC: We've discussed how stabilizing `Infallible` made more difficult the stabilization of the never type.

scottmcm: It's because we want `Infallible` to be a type alias to never.

TC: Is there any sense in that all emtpy enums should coerce to `!`?

scottmcm: Maybe.  This may get into the problem of type parameter fallback.

```rust
let x = returns_bang(); // x is of type `()`
let y = returns_infallible(); // y is of type `Infallible`
```

waffle: If I recall correctly, the problem with type fallback is that for generic functions, we currently infer unit, but we want to infer bang.  But if we infer bang, then existing code become UB.

scottmcm:

```rust
if false { panic!() } else { transmute(()) }
```

This is not UB today.  But if the `panic!()` inferred to bang, then it would be UB.

A trunsmute creating a `!` is obvious immediate UB.  Since the transmute is unconstrained, changing the type of `panic!()` changes the `dst` type of `transmute` from unit to bang.

TC: We needed to circle back to:

```rust=
let _: () = *x; // Insta-UB or compiler error?
```

scottmcm: Even if we say that the place can't be coerced, that could still do the place to value coercion, and then convert that.

waffle: The place to value coercion happens at the `let` level...

scottmcm: And we wouldn't be asking for the value?

TC: It seems like we're saying it's at least insta-UB, and any insta-UB that the compiler can find is of course good.

scottmcm: I might put this in a deny-by-default lint rather than a compiler error category.

TC: +1.

scottmcm: You only get the coercion if it's literally a coercion to `!`.  If it's a pointer to a generic type, and that happens to be substituted to `!`, then...

waffle:

```rust
unsafe fn foo<T>(p: *const T) {
    // doesn't compile because generics don't work like that
    let _: () = *p; //~ ERROR
}
// so you only hit that if it's literally bang, like
unsafe fn bar(p: *const !) {
    let _: () = *p;
}
// and nobody would ever write that.
```

scottmcm: If `bar` is UB to call but compiles, then I'm OK with that.  Don't write that.

scottmcm: Do we want a crater run?

TC: What would we expect crater to hit?

waffle: Not doing place coercions should make strictly less code compile.

scottmcm: What classes of things would hit this?

scottmcm: If we could make this be the rule, that'd be great.

*Consensus*: It's not UB to have an invalid thing in a place.  But it's UB to coerce that invalid place to a value.  And anywhere that the compiler can statically determine that insta-UB is happening, that would be a good spot for a deny-by-default lint, and it'd also be fine to hard error on those cases if that's easier.

Ralf's comment here <https://github.com/rust-lang/rust/issues/117288#issuecomment-1813030483>

scottmcm: Where this may break is the use of the never type hack, but that's probably OK.

waffle:

```rust
trait Hack {
    type Out;
}

impl<T> Hack for fn() -> T {
    type Out = T;
}

type Never = <fn() -> ! as Hack>::Out;
```

scottmcm: More details: https://github.com/rust-lang/never-type-initiative

(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

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

### "Language design principles" lang-team#189

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

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

### "The #[diagnostic] attribute namespace" lang-team#204

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

### "Rust 2024 survey" lang-team#209

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

### "Extern types V2 RFC" lang-team#211

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

### "Capturing lifetimes in `impl Trait`" lang-team#215

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

### "RFC review Inherent Trait Impls -- RFC#2375" lang-team#217

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

### "RFC review: Add f16 and f128 float types -- RFC#3453" lang-team#218

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

### "RFC review: MaybeDangling -- RFCS#3336" lang-team#219

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

### "Design meeting: Decide about the future for consts in patterns" lang-team#220

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

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

### "Meeting proposal: Unsafe extern blocks" lang-team#223

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

### "Design meeting: Implementable trait aliases" lang-team#224

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

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

### "Design meeting: resolve ABI issues around target-feature" lang-team#235

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

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

### "Website broken" lang-team#238

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