---
title: Triage meeting 2023-11-22
tags: ["T-lang", "triage-meeting", "minutes"]
date: 2023-11-22
discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202023-11-22
url: https://hackmd.io/qANW1hcYSTSVGRUQaXoEjw
---
# T-lang meeting agenda
- Meeting date: 2023-11-22
## Attendance
- People: TC, Josh, scottmcm, pnkfelix, Urgau, Waffle
## Meeting roles
- Minutes, driver: TC
## Scheduled meetings
- 2023-11-29: "weak alias types for Rust 2024" [#227](https://github.com/rust-lang/lang-team/issues/227)
Edit the schedule here: https://github.com/orgs/rust-lang/projects/31/views/7.
## Nominated RFCs, PRs, and issues
### "Add an experimental feature gate for function delegation" rust#117978
**Link:** https://github.com/rust-lang/rust/pull/117978
TC: Josh proposed this for priority discussion.
TC: petrochenkov is seeking a lang team liaison for a function delegation experiment. Per petrochenkov:
> How this proposal is different from the previous ones:
>
> - This proposal follows the "prototype first, finalized design later" approach, so it's oriented towards compiler team as well, not just language team. The prototyping is already [in progress](https://github.com/Bryanskiy/rust/tree/delegImpl) and we are ready to provide resources for getting the feature to production quality if accepted.
>
> - This proposal takes a more data driven approach, and builds the initial design on relatively detailed statistics about use of delegation-like patterns collected from code in the wild. The resulting design turns out closer in spirit to the [original proposal](<https://github.com/rust-lang/rfcs/pull/1406>) by @contactomorph than to later iterations.
TC: Here's the eRFC (he knows that eRFCs are dead):
https://github.com/petrochenkov/rfcs/blob/delegation/text/0000-fn-delegation.md
https://github.com/rust-lang/rfcs/pull/3530
Josh: Anyone want to liaison for this?
...
TC: I'll do it.
all: Great.
*Consensus*: Let's do this; TC will liaison.
---
TC: Someone brought up that, strictly speaking, the process as documented requires an FCP, but we haven't been doing that. Are we OK with a meeting consensus for this?
scottmcm: I'm a fan of meeting consensus.
pnkfelix/Josh: No problem with that.
---
Josh: Not blocking the experiment, but maybe we should propose FCP merge on the RFC also, since it seems mostly complete.
pnkfelix: Nikomatsakis described a process in late October killing off eRFCs. In line with that, let's maybe start with the experiment. We don't want to send mixed signals on eRFCs.
TC: The problem here is that he labeled it as an eRFC.
scottmcm: Agreed. Josh, if you're confident in it and want to propose FCP merge on this as a normal RFC, do that.
*Consensus*: Let's do the experiment, we'll encourage this to be relabeled as a normal RFC, and Josh may propose FCP merge.
### "Add `never_patterns` feature gate" rust #118157
**Link:** https://github.com/rust-lang/rust/pull/118157
TC: Nadrieril is proposing to start an experiment to move forward the never type:
TC: The details are here:
- https://github.com/rust-lang/rust/issues/118155
- https://hackmd.io/hcnbjw2PS0GGfb2Tzl2r8g
TC: scottmcm agreed to be the liaison. Do we agree this can go forward?
all: Let's do this.
*Consensus*: Let's do this.
### "Arbitrary self types v2" rfcs#3519
**Link:** https://github.com/rust-lang/rfcs/pull/3519
TC: Niko nominated this:
> I'm nominated to take the temperature of the @rust-lang/lang team on this RFC -- I'd like to see it move forward!...
>
> One thing I would note is that I think that the RFC should highlight more that it also enables `*const self` methods -- this is a big win for unsafe code, in my opinion, for all the same reasons. Right now code that wants to take a raw pointer and doesn't want to guarantee reference validity is pretty stuck.
TC: I read through the RFC some weeks ago, and it looked reasonable to me.
TC: However, relevant to Niko's point, two types are excluded from being receivers, `NonNull` and `Weak`. What do we think about that?
Josh: Maybe we could fix this over an edition.
scottmcm: I'm a fan of trying to do something better. We have a lot of methods on pointers though. Moreover, the strict provenance work will add many more methods to pointers. What's the difference between raw pointers and `NonNull` here?
scottmcm: Also, what's the difference between `Weak` and `Mutex`? Or `MaybeUninit`?
Josh: Maybe we could have a rule where the methods on the inner thing would win.
pnkfelix: How would that work with generics?
scottmcm: We know how to disambiguate in one direction but not the other. People can't write their own inherent methods on `Mutex`. It'd be inherents first, then this other thing, then trait methods.
Josh: You could have `impl _ for Box<T>` and `fn foo(self)` or `impl _ for T` and `fn foo(self: Box<Self>)`.
(Discussion of whether we even need the first with this. We decided that yes, we do.)
Josh: Receiver is less scary to opt-into than fundamental. We could have a resolution rule where if you opt into Receiver, then someone can implement a method on their own arbitrary type that takes Receiver as Self, and then we'd prioritize the method taking `TheReceiver<Self>` over methods on `TheReceiver`. We can't prioritize the other way or any new method on `TheReceiver` would be a breaking change.
pnkfelix: The RFC goes both ways on suggesting that we might or might not want to encourage receivers on raw pointers. What do people think about that?
scottmcm: When working around stacked borrows issues, you sometimes really want this.
Josh: The RFC notes this, and says on the one hand maybe you want to wrap these in a type, but on the other, raw pointer receivers have been in nightly for years and haven't been a problem.
waffle: We already have receivers on pointers in the standard library with safe methods.
*General outcome*: We want to find some way to enable this, including for raw pointers and `NonNull` and (maybe) `Weak` but we don't know how to do that yet. We'd like more discussion about either the resolution rule Josh proposed or about what a type is committing to when it implements Receiver with respect to adding new methods. And we'd like more discussion about why the RFC distinguished `NonNull` and raw pointers.
*Consensus*: Josh and scottmcm will write a comment about each of their thoughts here.
---
#### Post-meeting observations
[Observations after the meeting relevant to the discussion...]
#### What guarantees a type that implements `Receiver` is making
TC: The RFC does discuss the issue of what guarantees a type implementing `Receiver` is making about the methods that it adds. The key point it makes is that this is no worse than what's already true for `Deref`, and that we already have this clearly documented.
> ## Method shadowing
>
> For a smart pointer `P<T>` that implements `Deref<Target = T>`, a method call `p.m()` might call a method `P::m` on the smart pointer type itself, or it might call `T::m`. If both methods are declared, this results in an error.
>
> Rust standard library smart pointers are designed with this shadowing behavior in mind:
>
> * `Box`, `Pin`, `Rc` and `Arc` heavily use associated functions rather than methods.
> * Where they use methods, it's often with the _intention_ of shadowing a method in the inner type (e.g. `Arc::clone`).
>
> Furthermore, the `Deref` trait itself [documents this possible compatibility hazard](https://doc.rust-lang.org/nightly/std/ops/trait.Deref.html#when-to-implement-deref-or-derefmut), and the Rust API Guidelines has [a guideline about avoiding inherent methods on smart pointers](https://rust-lang.github.io/api-guidelines/predictability.html#smart-pointers-do-not-add-inherent-methods-c-smart-ptr).
>
> These method shadowing risks also apply to `Receiver`. This RFC does not make things worse for types that implement `Deref`, it only adds additional flexibility to the `self` parameter type for `T::m`.
TC: This was also discussed in a [thread](https://github.com/rust-lang/rfcs/pull/3519/files#r1379664429) in the RFC PR. Here was the winning argument (thanks to Nadrieril) that `Deref` has an equivalent existing problem:
Suppose we have these three crates, `a`, `b`, `c`:
```rust
// crate: a
use core::ops::Deref;
pub struct A<T>(pub T);
impl<T> Deref for A<T> {
type Target = T;
fn deref(&self) -> &Self::Target { &self.0 }
}
```
```rust
// crate: b
pub struct B;
pub struct BShow;
impl B {
pub fn show(&self) -> BShow { BShow }
}
```
```rust
// crate: c
// depends-on: a, b
use a::A;
use b::{BShow, B};
fn main() {
let _: BShow = A(B).show(); //~ OK.
}
```
The claim is that in doing this, crate `a` has promised, on pain of a *minor* breaking change, to never add any new inherent methods to `A`. If it does so, e.g.:
```rust
// crate: a
pub struct AShow;
impl<T> A<T> {
pub fn show(&self) -> AShow { AShow }
}
```
Then in crate `c`, we get:
```rust
// crate: c
// depends-on: a, b
use a::A;
use b::{BShow, B};
fn main() {
let _: BShow = A(B).show();
//~^ ERROR mismatched types
//~| NOTE expected `BShow`, found `AShow`
}
```
[Playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=%2F%2F+crate%3A+a%0Amod+a+%7B%0A++++use+core%3A%3Aops%3A%3ADeref%3B%0A++++pub+struct+A%3CT%3E%28pub+T%29%3B%0A++++impl%3CT%3E+Deref+for+A%3CT%3E+%7B%0A++++++++type+Target+%3D+T%3B%0A++++++++fn+deref%28%26self%29+-%3E+%26Self%3A%3ATarget+%7B%0A++++++++++++%26self.0%0A++++++++%7D%0A++++%7D%0A%0A++++%23%5Ballow%28dead_code%29%5D%0A++++pub+struct+AShow%3B%0A++++%23%5Bcfg%28False%29%5D%0A++++impl%3CT%3E+A%3CT%3E+%7B%0A++++++++pub+fn+show%28%26self%29+-%3E+AShow+%7B%0A++++++++++++AShow%0A++++++++%7D%0A++++%7D%0A%7D%0A%0A%2F%2F+crate%3A+b%0Amod+b+%7B%0A++++pub+struct+B%3B%0A++++pub+struct+BShow%3B%0A++++impl+B+%7B%0A++++++++pub+fn+show%28%26self%29+-%3E+BShow+%7B%0A++++++++++++BShow%0A++++++++%7D%0A++++%7D%0A%7D%0A%0A%2F%2F+crate%3A+c%0A%2F%2F+depends-on%3A+a%2C+b%0Ause+a%3A%3AA%3B%0Ause+b%3A%3A%7BBShow%2C+B%7D%3B%0A%0Afn+main%28%29+%7B%0A++++let+_%3A+BShow+%3D+A%28B%29.show%28%29%3B%0A++++%2F%2F~%5E+ERROR+mismatched+types%0A++++%2F%2F~%7C+NOTE+expected+%60BShow%60%2C+found+%60AShow%60%0A%7D%0A)
### "Macro fragment specifiers edition policy" rfcs#3531
**Link:** https://github.com/rust-lang/rfcs/pull/3531
TC: In the 2024 edition planning meeting on 2023-11-15, we discussed what to do about the `expr` fragment specifier having diverged from the underlying grammar. We decided that we should draft a policy that would cover cases like this and publish it as an RFC. This is that RFC.
JT: Looks like what we agreed.
JT: In the background section, are there any cases where we could change a fragment specifier?
scottmcm: Looks like it's legal for us to make a reserved keyword start working inside an edition because the reserved keyword does match `expr`.
```rust
macro_rules! foo {
($e:expr) => {1};
($t:tt) => {2};
}
fn main() {
foo!(try);
}
```
gives
```text=
error: expected expression, found reserved keyword `try`
--> src/main.rs:7:10
|
2 | ($e:expr) => {1};
| ------- while parsing argument for this `expr` macro fragment
...
7 | foo!(try);
| ^^^ expected expression
```
<https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c8dfce652d2589cfd920fcfbcf3b2537>
JT: I'll propose FCP merge.
*Consensus*: We'll propose FCP merge.
### "guarantee that char and u32 are ABI-compatible" rust#118032
**Link:** https://github.com/rust-lang/rust/pull/118032
TC: We're being asked to approve the following diff:
```diff
-/// `char` is guaranteed to have the same size and alignment
-/// as `u32` on all platforms.
+/// `char` is guaranteed to have the same size, alignment, and
+/// function call ABI as `u32` on all platforms.
```
TC: RalfJ gives the context:
> In #116894 we added a guarantee that `char` has the same alignment as `u32`, but there is still one axis where these types could differ: function call ABI. So let's nail that down as well: in a function signature, `char` and `u32` are completely equivalent.
>
> This is a new stable guarantee, so it will need t-lang approval.
scottmcm: The only way we could care is if there were some system that wanted to pass less than the full 32 bits. That seems unlikely.
JT: Does Ralf mean for this to only affect Miri, or does he also want us to make a guarantee on the Rust side?
scottmcm: RalfJ probably means for us to make a guarantee on the Rust side also. The opsem team are trying to write rules about this.
waffle: You could, e.g., transmute one function pointer to another and the call would still work.
scottmcm: This comes up in extern C and in unsafe code.
Josh: This makes sense on the C side, but what are we gaining on the Rust ABI side?
(Discussion of that...)
TC: The other thing to consider is that since we already guarantee size and alignment, people are going to get confused and rely on this whether we guarantee it or not.
waffle: It's a lot saner and simpler to think about things if this guarantee is true.
scottmcm: I'll propose FCP merge for T-lang.
*Consensus*: We'll propose FCP merge.
### "Add warn-by-default lint against unclear fat pointer comparisons" #117758
**Link:** https://github.com/rust-lang/rust/pull/117758#issuecomment-1823115237
scottmcm: I made a concrete proposal here, and proposed FCP merge.
(Some discussion about odd use cases.)
pnkfelix: This does look right.
(The meeting ended here.)
### "TAIT decision on "may not define may guide inference"" rust#117865
**Link:** https://github.com/rust-lang/rust/issues/117865
TC: The question is whether this should be true:
> The compiler is allowed to rely on whether or not an item is allowed to define the hidden type of an opaque type to guide inference.
Here's the door that this would close:
> If this rule is adopted, then after TAIT is stabilized, it will not be possible in a fully backward compatible way to later change the rules that determine whether or not an item is allowed to define the hidden type in such a way that an item in existing code that uses an opaque type could switch (without any code changes) from being not allowed to define its hidden type to being allowed to define it.
TC: This is of importance to the new trait solver.
TC: Here's one reason for this. When we're type checking a body and we find an opaque type, we sometimes have to decide, should we infer this in such a way that this body would define the hidden type, or should we treat the type as opaque (other than auto trait leakage) and infer based on that? Depending on that, we can get different answers.
TC: If we did not let inference rely on this, then we would be closing the door on later *allowing* inference to rely on this without provoking changes in inference.
TC: (This question is entirely orthogonal to how we notate whether an item is allowed to define the hidden type of an opaque. Answering this question in the affirmative would update one element of the [#107645 FCP][].)
[#107645 FCP]: https://github.com/rust-lang/rust/issues/107645#issuecomment-1571789814
### "Stabilize THIR unsafeck" rust#117673
**Link:** https://github.com/rust-lang/rust/pull/117673
TC: matthewjasper describes the change:
> * Removes `-Zthir-unsafeck`, stabilizing the behaviour of `-Zthir-unsafeck=on`.
> * Removes MIR unsafeck.
> * Union patterns are now unsafe unless the field is matched to a wildcard pattern.
TC: ...and gives context for the nomination:
> Nominating for T-lang discussion. This is mostly an internal change, but there are a couple of differences between THIR and MIR unsafeck that are visible to users.
>
> * Union patterns are considered to access fields (and so need `unsafe`) in more cases, crater could not find any code this breaks (see [Which patterns on union fields should be considered safe? #87520](https://github.com/rust-lang/rust/issues/87520) for some previous discussion)
>
> ```rust
> let U { f } = u; // access for both checkers
> let U { f: () } = u; // only an access in THIR unsafeck
> let U { f: _ } = u; // not an access in either cheker
> ```
>
> * Some error spans are slightly better in THIR unsafeck
> * Some _lint_ spans are slightly different in THIR unsafeck. Because `unsafe_op_in_unsafe_fn` is not currently a backwards compatibility lint, nor reported in external macros, this can change whether it's reported. This can break code with `deny(unsafe_op_in_unsafe_fn)` when not compiled with `--cap-lints`. Crater found one place where this happened.
### "References refer to allocated objects" rust#116677
**Link:** https://github.com/rust-lang/rust/pull/116677
TC: To the page about [`reference`](https://doc.rust-lang.org/std/primitive.reference.html), the proposal is to add this language:
> #### Safety
>
> For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, unsafe code may assume that the following properties hold. Rust programmers must assume that, unless explicitly stated otherwise, any Rust code they did not author themselves may rely on these properties, and that violating them may cause that code to exhibit undefined behavior.
>
> * `t` is aligned to `align_of_val(t)`
> * `t` is dereferenceable for `size_of_val(t)` many bytes
>
> If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range `[a, a + N)` is all contained within a single allocated object.
### "static mut: allow mutable reference to arbitrary types, not just slices and arrays" rust#117614
**Link:** https://github.com/rust-lang/rust/pull/117614
TC: RalfJ nominated this for us:
> For historical reasons, we allow this:
>
> ```rust
> static mut ARRAY: &'static mut [isize] = &mut [1];
> ```
>
> However, we do not allow this:
>
> ```rust
> static mut INT: &'static mut isize = &mut 1;
> ```
>
> I think that's terribly inconsistent. I don't care much for `static mut`, but we have to keep it around for backwards compatibility and so we have to keep supporting it properly in the compiler. In recent refactors of how we deal with mutability of data in `static` and `const`, I almost made a fatal mistake since I tested `static mut INT: &'static mut isize = &mut 1` and concluded that we don't allow such `'static` mutable references even inside `static mut`. After all, nobody would expect this to be allowed only for arrays and slices, right?!?? So for the sake of our own sanity, and of whoever else reverse engineers these rules in the future to understand what the Rust compiler accepts or does not accept, I propose that we accept this for all types, not just arrays and slices.
### "Properly reject `default` on free const items" rust#117818
**Link:** https://github.com/rust-lang/rust/pull/117818
TC: fmease explains:
> The following code compiles successfully while it should lead to an error due to the presence of the contextual keyword `default` on the _free_ constant item:
>
> ```rust
> default const K: () = ();
> fn main() {}
> ```
>
> The AST validation code was incorrectly implemented and only rejects `default` on free const items that _don't_ have a body:
>
> ```rust
> default const K: ();
> ```
>
> Technically speaking, this is a breaking change but I doubt it will lead to any real-world regressions (maybe in some macro-trickery crates?). Doing a crater run probably isn't worth it.
### "incorrect UB when when a `!` place is constructed (but not loaded!)" rust#117288
**Link:** https://github.com/rust-lang/rust/issues/117288
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 = ! ?
> }
> }
> ```
### "Document that <- is a single token" reference#1424
**Link:** https://github.com/rust-lang/reference/pull/1424
TC: The question is whether to add this line to the reference:
> | `<-` | LArrow | The left arrow symbol has been unused since before Rust 1.0, but it is still treated as a single token
The background, per mattheww, is that:
> `<-` was the "move operator", removed in Rust 0.5, but is still lexed as a single token.
ehuss notes:
> Since there was an attempt to remove this that was then later backed out, I'm assuming the language team agrees that the emplacement operator has to stay permanently. However, I'm not 100% sure based on [rust-lang/rust#50832 (comment)](https://github.com/rust-lang/rust/issues/50832#issuecomment-389884751).
>
> Since I'm not completely confident that the language team doesn't want to try to remove this in the future, I'm going to nominate this for their attention for approval. I think this PR probably should be merged. I wouldn't be surprised if there were more macros using it since the last time it was attempted to be removed.
Back in 2018, Niko had said:
> Discussed in the @rust-lang/compiler meeting. I think we reached this consensus:
>
> * in this case, yes, we should do as @petrochenkov suggests: keep parsing, error in AST validation
> * if in the future, if it happens that we want to repurpose the syntax, we deal with it then: best of course is to use an edition for it, but maybe by then there no longer exist crates using it
> * going forward, it would be ideal if we could do some kind of "pre-cfg / expansion" feature check to try and avoid this in the future; that may or may not be feasible though, and we couldn't do it retroactively for all existing things anyway
### "Add `wasm_c_abi` `future-incompat` lint" rust#117918
**Link:** https://github.com/rust-lang/rust/pull/117918
TC: daxpedda gives the context:
> This is a warning that will tell users to update to `wasm-bindgen` v0.2.88, which supports spec-compliant C ABI.
>
> The idea is to prepare for a future where Rust will switch to the spec-compliant C ABI by default; so not to break everyone's world, this warning is introduced.
>
> Addresses https://github.com/rust-lang/rust/issues/71871
### "Decision: semantics of the `#[expect]` attribute" rust#115980
**Link:** https://github.com/rust-lang/rust/issues/115980
TC: @nikomatsakis gives this background:
> This issue is spun out from #54503 to serve as the decision issue for a specific question. The question is what the 'mental model' for the `expect` attribute should be. Two proposed options:
>
> 1. The expectation is fulfilled, if a #[warn] attribute in the same location would cause a diagnostic to be emitted. The suppression of this diagnostic fulfills the expectation. ([src](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Expect.20attribute.20mental.20model/near/341522535)) (Current implementation in rustc)
> 2. The expectation is fulfilled if removing the `#[expect]` attribute would cause the warning to be emitted. ([src](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Expect.20attribute.20mental.20model/near/354082551))
>
> @xFrednet created a [list of use cases](https://hackmd.io/@xFrednet/expect-attr-use-cases) to help with the discussion of these two models; they found both models work equally well, except for [use case 4](https://hackmd.io/@xFrednet/expect-attr-use-cases#Use-case-4-Suppress-lints-from-CI) which would only be possible with the first model.
TC: ...and proposes that we adopt option 1.
### "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.
### "Remove ability to disable some target features" rust#116584
**Link:** https://github.com/rust-lang/rust/pull/116584
TC: RalfJ nominated this one, and he has a corresponding design meeting proposal:
> We'd like to remove the ability to disable certain target features. The broad goal we are going for here is that **code built for the same target is ABI-compatible no matter the target features**. This is an easy rule to remember and a principle that it seems reasonable to enforce. This principle is currently violated in several ways (for x86, that's tracked in #116344 and #116558). This PR is one part of achieving that, [this pre-RFC](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Pre-RFC.20discussion.3A.20Forbidding.20SIMD.20types.20w.2Fo.20features) is another part, and then one final piece is needed to reject `+x87`/`+sse` on `x86_64-unknown-none` (or to reject float-taking/float-returning-functions) as that would similarly change the ABI.
>
> ...
>
> I have created a [design meeting proposal](https://github.com/rust-lang/lang-team/issues/235) for the wider problem space here, in case you think this needs more fundamental discussion.
### "Uplift `clippy::precedence` lint" rust#117161
**Link:** https://github.com/rust-lang/rust/pull/117161
TC: The proposal is to lint against:
```rust
-2.pow(2); // Equals -4.
1 << 2 + 3; // Equals 32.
```
These would instead be written:
```rust
-(2.pow(2)); // Equals -4.
1 << (2 + 3); // Equals 32.
```
Prompts for discussion:
- Is this an appropriate lint for `rustc`?
- How do other languages handle precedence here?
- Is minus special enough to treat differently than other unary operators?
### "TAIT decision on "may define implies must define"" rust#117861
**Link:** https://github.com/rust-lang/rust/issues/117861
TC: The question is whether this should be true:
> At least until the new trait solver is stabilized, any item that is allowed to define the hidden type of some opaque type *must* define the hidden type of that opaque type.
TC: This is important for the new trait solver.
TC: Here's one reason for that. The new trait solver treats strictly more code as being a defining use. It's also more willing to reveal the hidden type during inference if that hidden type is defined within the same body. This rule helps to avoid inference changes when moving from the old solver to the new solver. Adding this restriction makes TAIT roughly equivalent to RPIT with respect to these challenges.
TC: (This question is entirely orthogonal to how we notate whether an item is allowed to define the hidden type of an opaque.)
### "TAIT decision on whether nested inner items may define" rust#117860
**Link:** https://github.com/rust-lang/rust/issues/117860
TC: The question is whether this should be true:
> Unless and until [RFC PR 3373](https://github.com/rust-lang/rfcs/pull/3373) is accepted and scheduled for stabilization in some future edition, items nested inside of other items may define the hidden type for opaques declared outside of those items without those items having to recursively be allowed to define the hidden type themselves.
The context is that we allow this:
```rust
trait Trait {}
struct S;
const _: () = {
impl Trait for S {} // Allowed.
};
```
Should we accept spiritually-similar TAIT code unless and until we decide to go a different direction with the language?
### "TAIT decision on "must define before use"" rust#117866
**Link:** https://github.com/rust-lang/rust/issues/117866
TC: The question is whether the following should be true:
> If the body of an item that may define the hidden type of some opaque does define that hidden type, it must do so syntactically _before_ using the opaque type in a non-defining way.
One of the big design questions on TAIT is whether we'll be able to later lift the "may define implies must define" rule after we land the new trait solver. The answer to that question could inform other design decisions, such as how to notate whether an item is allowed to define the hidden type of an opaque.
The restriction here is designed to make it more likely (hopefully much more likely) that we can later lift the "may define implies must define" restriction.
### "`.await` does not perform autoref or autoderef" rust#111546
**Link:** https://github.com/rust-lang/rust/issues/111546
TC: This was nominated for T-lang by WG-async. @tmandry said:
> We discussed this in a recent wg-async meeting ([notes](https://hackmd.io/G6ULofyXSIS4CK9u-jwYRg)). The consensus was that we thought the change was well-motivated. At the same time, we want to be cautious about introducing problems (namely backwards compatibility).
>
> There should probably be a crater run of this change, and we should also work through any problematic interactions that could be caused by this change. (@rust-lang/types should probably weigh in.)
>
> The main motivation for the change is the analogy to `.method()`, as well as to wanting async and sync to feel similarly convenient in most cases.
>
> Note that there is another analogy that works against this, the analogy to `IntoIterator`, where the lang-effect form (`for _ in foo {}`) does not do autoref/autoderef. However, given that this _looks_ very different from `foo.await`, and taking a reference with that form is significantly more convenient (`for x in &foo` or `for x in foo.iter()` vs `(&foo).await`), it seemed the analogy was stretched pretty thin. So we elected to put more weight on the above two considerations.
>
> That being said, this change would need lang team signoff. You can consider this comment wg-async's official recommendation to the lang team.
### "Support overriding `warnings` level for a specific lint via command line" rust#113307
**Link:** https://github.com/rust-lang/rust/pull/113307
TC: We discussed in the 2023-09-26 meeting, but were unsure of the question we were being asked. @jieyouxu has since replied:
> I believe I wanted to ask that if the command line indeed forms the root of the tree, or if it actually overrides the source annotations.
TC: On that basis, @tmandry replied:
> ### Nesting
>
> I think the command line (specifically `-A`, `-W`, `-D` flags) should form the root of the tree. We have `--cap-lints`, `--force-warn`, and `-F` (forbid) for overriding the source. (Actually the mental model documented in the [rustc book](https://doc.rust-lang.org/rustc/lints/levels.html) is that `force-warn` and `forbid` still form the root of the tree, but cannot be overridden; I think the distinction is mostly academic.)
>
> That's almost all the expressive power one could want along this axis. One wrinkle is that `--forbid` is overridden by `--cap-lints`, while `--force-warn` is not. If we wanted full fine-grained control we could always add `--force-allow` and `--force-deny`.
>
> ### `warnings`
>
> Regarding the meaning of `warnings`, it _is_ a simpler mental model for this to mean "the set of things that are warn-by-default". But this ignores what I perceive to be a common (and valid) use case, which is to disallow _all_ warnings in a codebase: In other words, prevent code from being checked in that causes warnings to be printed to a user's screen. Of course, for this to be practical one must control the version of rustc being used to build a codebase, but that is common in monorepo setups.
>
> ### Conclusion
>
> Given that there is an existing use case that relies on documented behavior, I think we should continue to treat `warnings` as a "redirect" for all warnings that come out of a particular level of the tree. Interpreting `-Awarnings -Wfoo` in the way proposed by this PR would muddy the (already complicated) mental model and add inconsistency between CLI and the command line, as noted by @oli-obk.
>
> A different group, like `default-warnings`, could be used to mean "the set of things that are warn-by-default". The compiler could further warn users that specify `-Awarnings -Wfoo` on the command line to use `-Adefault-warnings -Wfoo` instead.
### "Disallow future-incompatibility lints in the 2024 edition" rust#117921
**Link:** https://github.com/rust-lang/rust/issues/117921
TC: We discussed this on 2023-11-15 and decided that we'd like an RFC with a policy about this going forward. For the existing lints, we wanted someone to break them into groups and propose which should be hard errors in every edition, which should be hard errors in the next edition, etc.
## 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
### "Add missing CNAME file for GitHub pages" lang-team#239
**Link:** https://github.com/rust-lang/lang-team/pull/239
## RFCs waiting to be merged
None.
## `S-waiting-on-team`
### "Tracking issue for dyn upcasting coercion" rust#65991
**Link:** https://github.com/rust-lang/rust/issues/65991
### "Stabilize `anonymous_lifetime_in_impl_trait`" rust#107378
**Link:** https://github.com/rust-lang/rust/pull/107378
### "make matching on NaN a hard error" rust#116284
**Link:** https://github.com/rust-lang/rust/pull/116284
### "Fix `non_camel_case_types` for screaming single-words" rust#116389
**Link:** https://github.com/rust-lang/rust/pull/116389
### "warn less about non-exhaustive in ffi" rust#116863
**Link:** https://github.com/rust-lang/rust/pull/116863
### "Add an experimental feature gate for function delegation" rust#117978
**Link:** https://github.com/rust-lang/rust/pull/117978
### "guarantee that char and u32 are ABI-compatible" rust#118032
**Link:** https://github.com/rust-lang/rust/pull/118032
## Proposed FCPs
**Check your boxes!**
### "RFC: inherent trait implementation" rfcs#2375
**Link:** https://github.com/rust-lang/rfcs/pull/2375
### "unsafe attributes" rfcs#3325
**Link:** https://github.com/rust-lang/rfcs/pull/3325
### "MaybeDangling" rfcs#3336
**Link:** https://github.com/rust-lang/rfcs/pull/3336
### "add float semantics RFC" rfcs#3514
**Link:** https://github.com/rust-lang/rfcs/pull/3514
### "Stabilise inline_const" rust#104087
**Link:** https://github.com/rust-lang/rust/pull/104087
### "Implement `PartialOrd` and `Ord` for `Discriminant`" rust#106418
**Link:** https://github.com/rust-lang/rust/pull/106418
### "Stabilize `anonymous_lifetime_in_impl_trait`" rust#107378
**Link:** https://github.com/rust-lang/rust/pull/107378
### "Report monomorphization time errors in dead code, too" rust#112879
**Link:** https://github.com/rust-lang/rust/pull/112879
### "`c_unwind` full stabilization request: change in `extern "C"` behavior" rust#115285
**Link:** https://github.com/rust-lang/rust/issues/115285
### "Decision: semantics of the `#[expect]` attribute" rust#115980
**Link:** https://github.com/rust-lang/rust/issues/115980
### "Fix `non_camel_case_types` for screaming single-words" rust#116389
**Link:** https://github.com/rust-lang/rust/pull/116389
### "Exhaustiveness: reveal opaque types properly" rust#116821
**Link:** https://github.com/rust-lang/rust/pull/116821
### "Prevent opaque types being instantiated twice with different regions within the same function" rust#116935
**Link:** https://github.com/rust-lang/rust/pull/116935
### "Stabilize Wasm target features that are in phase 4 and 5" rust#117457
**Link:** https://github.com/rust-lang/rust/pull/117457
### "Stabilize Wasm relaxed SIMD" rust#117468
**Link:** https://github.com/rust-lang/rust/pull/117468
## Active FCPs
### "Stabilize C string literals" rust#117472
**Link:** https://github.com/rust-lang/rust/pull/117472
## P-critical issues
None.