--- title: Triage meeting 2023-11-29 tags: ["T-lang", "triage-meeting", "minutes"] date: 2023-11-29 discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202023-11-29 url: https://hackmd.io/1EjTzH21SK6_fyySOmp4zg --- # T-lang meeting agenda - Meeting date: 2023-11-29 ## Attendance - People: TC, nikomatsakis, Josh, Waffle, Urgau, eholk, scottmcm, pnkfelix ## 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. ## Announcements or custom items (Meeting attendees, feel free to add items here!) ## Nominated RFCs, PRs, and issues ### "Add lint against ambiguous wide pointer comparisons" rust#117758 **Link:** https://github.com/rust-lang/rust/pull/117758 TC: In the 2023-11-22 meeting, we decided to do this, but it has since become blocked on naming. Though "fat pointer" is the term of art in the academic literature, the literature of many other languages including C++, in Wikipedia, and in most Rust RFCs that have touched on this, we apparently haven't actually added this term anywhere to the *language*. So we need to answer with respect to the language whether we're happy with the term "fat pointer" or whether we want to use a different term for this such as "wide pointer" or "double pointer" or something else (j/k "double plus good pointer"?). **scottmcm** raised the point that we're planning to add [`Thin`](https://doc.rust-lang.org/core/ptr/traitalias.Thin.html) to the standard library, so we should probably be happy with whatever we choose that the term and its antonym match. TC: What do we think? scottmcm: I think if we RFCed `thin` someone else we should stick with it. But I don't care enough to argue about it. So I'm good going forward with the PR. pnkfelix: +1. Josh: Both "narrow" and "thin" seem like perfectly reasonable counterparts for "wide". *Consensus*: The lint name is fine. This is OK to go forward with the name change. ### "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. TC: What do we need to do to stabilize this? Niko: We need to understand the differences better. Some of the changes here were the point of doing this, of course. Josh: Note that we *could* potentially put something on top of this to preserve the same unsafety properties for unions, if we *wanted* to, but it doesn't seem like we need to. Niko: Usually we've held that the rules around unsafe are syntactical in nature. Niko: I'm generally in favor of this... overall it's an implementation decision. We don't care if it's THIR or MIR, we care what the semantic behavior is. Our side is the impact on users. Niko: I think it's fine to make more things unsafe for the time being. It should be predictable to users what is unsafe, so this makes sense to me. Niko: We should do this, but we should also formulate a better statement about the purpose and placement of the unsafe keyword. The purpose is to draw the attention of the reader and make that reader aware. So there's some tension between predictability and utility. Niko: I'll write a comment and check in with opsem about whether and why or why not this would be UB. Josh: It is technically a breaking change to make something that is safe become unsafe, or vice versa. The latter is a permitted breaking change, but disruptive. So we should identify if there are things we'll make unsafe that we might want to make safe again in the future. Are there any things other than union field matches into ZSTs that we'd want to make safe again? Waffle: Does this code trigger unsafe or not? ```rust let () = u.f; ``` ...it's currently unsafe. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=95d40c7b290538c1eb4b77ed9d0afc8a Josh: Given that we're relying on the syntax rather than on the underlying accesses, it makes sense we should leave it this way. Niko: +1. Niko: Both waffle's example and the pattern should either be UB or not, that's my feeling. I'd like T-opsem to bless this thinking. *Consensus*: Niko will write up a comment and check with T-opsem. --- Post-meeting notes... scottmcm wrote up a comment here: https://github.com/rust-lang/rust/pull/117673#issuecomment-1823383794 > Oh, great to see this! 🎉 I've been looking forward to it, but didn't know it was progressing. > > One thing I'm uncertain about: I see far fewer scopes in the MIR tests. Now, overall I'm generally happy for that, since simpler MIR good, but I'm not sure how changing the unsafe checker is changing the MIR build(?)ing? Is there another change in here? I'm paranoid about accidental scoping changes for `Drop`s. > > The changes you mention for unions and in [#117673 (comment)](https://github.com/rust-lang/rust/pull/117673#issuecomment-1807807253) all seem positive to me. > > (I'm also inclined to agree that it might be nice for this PR to just flip a flag, in case something catastrophic happens and it needs to be undone, but that's up to compiler folks to decide.) ### "Tracking issue for negative impls" rust#68318 **Link:** https://github.com/rust-lang/rust/issues/68318 T-libs-api nominated this for us. Amanieu: > This came up in the libs-api meeting today while we were discussing [rust-lang/libs-team#175](https://github.com/rust-lang/libs-team/issues/175) which proposes adding `PhantomUnSend` and `PhantomUnSync` types to the standard library. We feel that it would be better to solve the ergonomics issue (using `PhantomData` to opt out of `Send`/`Sync` is... ugly) with a proper language feature. > > How does the lang team feel about a partial stabilization of negative impls which only covers the specific use case of opting-out of [auto traits] like `Send`/`Sync`/`Unpin`? The proposal they're considering for `PhantomNotSend` / `PhantomNotSync` is motivated by the observation that, without some way to express this, people instead rely on the properties (and absence of properties) of existing types that aren't meant explicitly for this purpose, and this can act to constrain the evolution of the language. Niko: I'm in favor with one caveat. We should require that they cover all possible values. This is what we do for drop check for example. E.g.: ```rust struct Foo<T> { } impl<T> !Send for Foo<T> where T: Debug, {} // does this mean `T: !Debug => Foo<T>: Send` ``` Niko: The current behavior is, "we will add a positive impl for you if there is neither a positive or negative impl." Niko: Maybe we call this "no narrowed impls", or all negative impls must be ["always applicable"](https://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/). pnkfelix: For reference, I think this is the issue that describes the specific thing we put in for dropck: https://github.com/rust-lang/rust/issues/8142 pnkfelix: (Namely, we called it "Prohibit _specialized_ drops"). I don't know whether it is good or bad to use the term "specialize" there. It seemed apt at the time.) Waffle: are those equivalent? ```rust impl Send for Type where (): NeverHolds {} impl !Send for Type {} ``` Niko: They're not equivalent. They may be right now, but they won't always necessarily be. The negative impl is meaningful to coherence -- or we plan to make it meaningful. Niko: The rule for users is that you can never take back an impl. Whether positive or negative, it can't go away. Waffle: It's especially interesting in the context of T-libs-api question, because we might still want the opt-out types even if we stabilize negative impls. Because they are different. Niko: That's an interesting point. ```rust // Neither yes nor negative, but I reserve the right. impl ?Send for Type { } trait Foo { } impl<T> ?Foo for T { } // prohibits anything from implementing this trait Bar { } impl<T> ?Bar for Box<T> { } // I didn't do this for Box trait Baz { } impl<T> ?Baz for T where T: Fundamental { } // ...maybe we can even do this?? ``` Niko: This would prohibit anyone from implementing it outside of this trait. scottmcm: We could have this list be all the `fundamental` types. scottmcm: The other place this would be nice would be the on unimplemnted discussion, as phrasing in terms of an `impl` would be way nicer than repeating all of things impls can do into an attribute. Josh: So we comment that we're generally in favor of having these, and mention the necessary restrictions. Waffle: We may want both the phantom types because they're not equivalent to a negative impl, because the phantom types don't make a forward guarantee. Josh: That does suggest we should consider adding "questionable" impls. scottmcm: I'd love to see questionable impls. We'd use that in a lot of places and it'd be good to have it show in rustdoc. Josh: That raises a second question, if we do want questionable and negative impls, is there some way we could give guidance to the user to push the user toward questionable impl when they wrote negative impls? Josh: If we could attach visibility to trait items, that could be a hint about whether the user expected it to be a forward-compatibility guarantee or not. TC: But if you're doing it privately it has no effect. Josh: +1. scottmcm: Someone posted a pre-RFC somewhere about this: <https://internals.rust-lang.org/t/pre-rfc-scoped-impl-trait-for-type/19923> scottmcm: I don't think it discusses the trait solver implementation issues. It would probably be blocked on the work on the new solver. TC: Do we need an RFC, or is this a stabilization of something already specified, for the negative impls. Waffle: There is a tracking issue, but looking at it, apparently there is no RFC. scottmcm: This probably dates all the back to original OBITS. scottmcm: I might be fine stabilizing negative impls on auto traits specifically without one. It certainly needs a good stabilization report. Waffle: I can try working on the work for stabilizing this. scottmcm: I'll leave a comment. *Consensus*: We'll comment that we are interested in the restricted stabilization, but this may not be equivalent to the phantom types. The reserved impls are more of a future problem, as negative impls are already implemented. --- Post-meeting notes... Josh left a comment here: https://github.com/rust-lang/rust/issues/68318#issuecomment-1832355185 > We discussed this in today's @rust-lang/lang meeting. We had a consensus in favor of stabilizing enough of negative impls here. > > The subset we'd be in favor of stabilizing would be to require that the negative impl be "always applicable". Effectively, the impls can't have any bounds other than those required for an instance of the type. So, if `struct Foo<T>` requires `T: Debug` then you can `impl<T> !Send for Foo<T> where T: Debug`, but if `struct Foo<T>` _doesn't_ require `T: Debug` then you can only `impl<T> !Send for Foo<T>` with no bounds on `T`. > > One further consideration: a negative impl `impl !Send for Foo` isn't just "this is not `Send`", it's a promise that it won't _become_ `Send` in the _future_. If a user wants "this is not `Send` but I'm making no promises that it won't be in the future", we would need something like `impl ?Send for Foo`. The lang team was generally in favor of adding this form as well. And Waffle followed up: > To add to the @joshtriplett's comment: > > 1. The "always applicable" rule is the same as we currently have for `Drop` > 2. The rule that is easy to remember with negative impls is: **it's always a breaking change to remove an implementation, both positive and negative ones** > > * This rule would be somewhat more complex with "questionable implementations" if we end up adding them, since then it would be okay to remove _those_ > > I've also volunteered to work on stabilization of this feature and related work here. And scottmcm commented: > More on "questionable" impls: > > * We've wanted these in the past for other reasons, and indeed have `#[rustc_reservation_impl]` (https://github.com/rust-lang/rust/pull/62661/files#diff-3f4f29f2f5d7a54d28195beb05a24a0736a64ffe35eb30d8e7b2227c6a2fd615R564) to make this possible in certain cases. > * I would love to have them in rustdocs for various things. If we can't yet agree on `f32: !Ord`, having a `reserved impl Ord for f32;` as a place to put "Look, it's intentional that this doesn't exist and here's what you should do instead". > * Similarly, that could replace a bunch of the `on_implemented` use cases. `reserved impl FromResidual<Option<_>> for Result<_, _>;` would be nicer than [doing that with text](https://github.com/rust-lang/rust/blob/abe34e9ab14c0a194152b4f9acc3dcbb000f3e98/library/core/src/ops/try_trait.rs#L227-L231), for example, and could hopefully let it use the real trait solver instead of a side system with its own quirks. > * They would also be great for new standard library traits, since they could start by always reserving impls for all our fundamental types. That would avoid problems like how we couldn't `impl Extend for &mut impl Extend` because of reference being fundamental, even though that would be useful to have. ### "Convert unused_tuple_struct_fields to warn-by-default" rust#118297 **Link:** https://github.com/rust-lang/rust/pull/118297 TC: I nominated this based on discussion in T-compiler. Essentially, back in 2022, we had asked for a warning about unused tuple struct fields to be done separately from `dead_code` because we were concerned that it may be difficult to fix these warnings without changing the field ordering. After we had asked for that, pnkfelix proposed a way that we could let people fix this without changing field ordering. That was implemented and is what our lint suggests and has been suggesting that people do to fix this. That would seem to resolve the concern that led us to separate out this lint. TC: The folks in T-compiler seemed to feel this should be part of `dead_code` since unused fields of other structs are `dead_code` and this is essentially just making that lint more complete. In more detail: > Regarding the T-lang nomination, one of the open questions here is whether this should be part of the `dead_code` lint now that we're making it warn-by-default. > > The motivation for making this part of `dead_code` is that unused fields of normal structs warn under `dead_code`, so this would be consistent. E.g.: > > ```rust > warning: field `a` is never read > --> src/lib.rs:1:12 > | > 1 | struct A { a: () } > | - ^ > | | > | field in this struct > | > = note: `#[warn(dead_code)]` on by default > ``` > > On 2022-01-25, T-lang [requested](https://github.com/rust-lang/rust/pull/92972#issuecomment-1021511970) this lint be separated from `dead_code` so that it could be introduced gradually and so people could disable it specifically. The motivation seems to have been the belief that this lint could be "harder to fix than removing named fields, because removing a positional field changes the indices of the following fields". > > However, after that decision, on 2022-01-26, @pnkfelix [suggested](https://github.com/rust-lang/rust/pull/92972#issuecomment-1021815408) a change to the lint that would allow people to resolve the warning without changing field indices: > > > ...I thought: "well, we should let people include () fields (i.e. not warn about them), and perhaps even have the lint diagnostic here suggest either removing the field or making it have () type. That would keep the indices unchanged." > > This change was [implemented](https://github.com/rust-lang/rust/pull/92972#issuecomment-1096739201) and is suggested as part of the error message, e.g.: > > ```rust > error: field is never read: `1` > --> $DIR/tuple-struct-field.rs:6:21 > | > LL | struct Wrapper(i32, [u8; LEN], String); > | ^^^^^^^^^ > | > help: change the field to unit type to suppress this warning while preserving the field numbering > | > LL | struct Wrapper(i32, (), String); > | > ``` > > In discussion in T-compiler in Zulip, the feeling seemed to be that this should be part of `dead_code`. Given the change suggested by @pnkfelix and implemented in the lint that resolves the issue of preserving field indices, do we now agree? TC: pnkfelix, it was your good idea. pnkfelix: I'm obviously in favor of my good idea. Josh: Don't think this should be the *default* fix suggestion, but the possibility of doing it seems useful for making refactors easier. scottmcm: Big fan of treating this like (braced) struct fields as much as we can. Waffle: +1 *Consensus*: We'll tell people we're OK with this being `dead_code`. ### "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. pnkfelix: There's no way to break these assumptions without unsafe code. scottmcm: In some sense, safety comments are never relevant to safe code. pnkfelix: +1. scottmcm: This is stated as a safety invariant, but it's maybe a validity invariant in part. Josh: The impression I have is that the semantics of Rust are that having a T or &T is insta-UB if it's not aligned. scottmcm: But is it static or dynamic alignment here? If you have a `&dyn Debug` and it's 1-aligned, is it insta-UB if the type is `u32`, or do you have to actually call it to provoke the UB? You can use the pointer metadata APIs to get one of these. pnkfelix: There's discussion of this in the linked issues, it was mentioned that the current docs don't as a rule distinguish safety from validity, and that this PR was trying to match that. scottmcm: RalfJ said: > I'm just realizing that this is making a commitment on something that I consider an open question we haven't settled yet -- the validity invariant of dyn-sized references. I think we want to keep the door open for only requiring the statically sized prefix to be dereferencable. For custom DSTs, I think we don't even have any other choice. So a strict reading of what this PR adds makes DSTs impossible. > > The _safety_ invariant requires the full size to be dereferenceable, of course. Waffle: Can we delegate to T-opsem? scottmcm: Actually, I don't think I object to what this says. There are places we could say something stronger, but what's here is OK. scottmcm: The only thing I'm worried about is the bit about talking about code you don't control. Can you actually do that in code you control? That's the validity part. pnkfelix: It sounds like they wanted us to weigh in on the safety vs invalidity invariants. So we should probably say something about this. pnkfelix: There's a procedural question here. The PR makes the language better, but perhaps someone could infer things from what it doesn't say. Josh: I'm not sure we could make a general rule there. It'll depend on whether the remaining inaccuracy seems dangerous or harmless. pnkfelix: We could say, "note that the validity is not yet decided". TC: Would we have consensus if that were added to the PR? scottmcm: I'd be OK with that then, yes. The other bits are absolutely something that has to be true. Josh: No strong opinion on when the validity invariant has to be enforced. scottmcm: If T is a slice rather than a dyn, then it might be entirely reasonable to say that &[u32] has to be 4-byte aligned as a validity invariant. Josh: No objection to going forward on the PR with the note that pnkfelix suggested. *Consensus*: We'll suggest noting explicitly that the validity is not yet decided, and with that change to the PR, we're OK with it going forward. We'll propose FCP merge. scottmcm: I'll propose FCP merge. (The meeting ended here.) ### "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 = ! ? > } > } > ``` 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 > ``` ### "RFC: Associated const underscore" rfcs#3527 **Link:** https://github.com/rust-lang/rfcs/pull/3527 TC: dtolnay proposes this RFC: > Allow `_` for the name of associated constants. This RFC builds on [RFC 2526](https://github.com/rust-lang/rfcs/pull/2526) which added support for free `const` items with the name `_`, but not associated consts. > > ```rust > // RFC 2526 (stable in Rust 1.37) > const _: () = { /* ... */ }; > > impl Thing { > // this RFC > const _: () = { /* ... */ }; > } > ``` > > Constants named `_` are not nameable by other code and do not appear in documentation, but are useful when macro-generated code must typecheck some expression in the context of a specific choice of `Self`. > > [Rendered](https://github.com/dtolnay/rfcs/blob/assocunderscore/text/0000-associated-const-underscore.md) Then programmerjake asked a critical question: > When does associated const code get run? at type definition? when substituting concrete types into generic arguments? never? so, if I write: > > ```rust > pub struct S<T>(T); > > impl<T> S<T> { > const _: () = assert!(core::mem::size_of::<T>() % 2 == 0); > } > ``` > > when does the `assert` get run? scottmcm nominated this for discussion: > I was all set to propose merge as "of course" until I saw the note about evaluation :/ > > I do agree that not evaluating it is consistent with named associated constants. > > Unfortunately, I feel like it would be particularly likely for someone to move a `const _: () = assert!(...);` into an associated constant and not notice that it's just never running. --- TC: As an aside of the main point here, Niko noted: > One further thought: the whole `const _: () = { .. }` thing was a total hack -- albeit, a useful one. I do wonder if it's time to add something more first-class, e.g. "anonymous modules", something like that. TC: Writing an RFC for anonymous modules is something I've been intending to do, as it could have some utility for TAIT and the 2024 lifetime capture rules. ### "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. ### "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. ### "`.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. ### "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 "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 "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 ### "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. ### "Arbitrary self types v2." rfcs#3519 **Link:** https://github.com/rust-lang/rfcs/pull/3519 TC: We discussed this extensively in the meeting on 2023-11-22 resulting in: > *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. ### "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? ### "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. ## 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 ## RFCs waiting to be merged None. ## `S-waiting-on-team` ### "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 lint against ambiguous wide pointer comparisons" rust#117758 **Link:** https://github.com/rust-lang/rust/pull/117758 ### "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 ### "Support async recursive calls (as long as they have indirection)" rust#117703 **Link:** https://github.com/rust-lang/rust/pull/117703 ### "Add lint against ambiguous wide pointer comparisons" rust#117758 **Link:** https://github.com/rust-lang/rust/pull/117758 ### "Properly reject `default` on free const items" rust#117818 **Link:** https://github.com/rust-lang/rust/pull/117818 ### "guarantee that char and u32 are ABI-compatible" rust#118032 **Link:** https://github.com/rust-lang/rust/pull/118032 ## Active FCPs ### "Macro fragment specifiers edition policy" rfcs#3531 **Link:** https://github.com/rust-lang/rfcs/pull/3531 ## P-critical issues None.