--- title: Triage meeting 2024-05-22 tags: ["T-lang", "triage-meeting", "minutes"] date: 2024-05-22 discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202024-05-22 url: https://hackmd.io/xvm67yRQTG6CmjAYLzsTog --- # T-lang meeting agenda - Meeting date: 2024-05-22 ## Attendance - People: TC, Josh, Santiago, eholk, tmandry, Mara, Amanieu, scottmcm, pnkfelix, Xiang ## Meeting roles - Minutes, driver: TC ## Scheduled meetings - 2024-05-22: "Design meeting: Review draft project goal slate" [#264](https://github.com/rust-lang/lang-team/issues/264) - 2024-05-29: "Design meeting: UnsafePinned" [#266](https://github.com/rust-lang/lang-team/issues/266) Edit the schedule here: https://github.com/orgs/rust-lang/projects/31/views/7. ## Announcements or custom items (Meeting attendees, feel free to add items here!) ### Guest attendee items TC: For any guests who are present, please note in this section if you're attending for the purposes of any items on (or off) the agenda in particular. Mara: - "[RFC] externally implementable functions" rfcs#3632 ### Moving right along TC: As we've been doing recently, due to the impressive backlog, I'm going to push the pace a bit. If it's ever too fast or you need a moment before we move on, please raise a hand and we'll pause. ### Design meeting at 12:30 EST / 09:30 PST / 17:30 CET TC: Remember that we have a design/planning meeting that starts half an hour after this call ends. ### Next meeting with RfL We're next meeting with RfL on 2024-05-22 to talk about RfL project goals. https://github.com/rust-lang/rfcs/pull/3614 ### RTN TC: Note that Niko now has a draft RFC on RTN: https://hackmd.io/KJaC_dhZTmyR_Ja9ghdZvg With discussion here: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/return-type.20notation Both tmandry and I have reviewed it. Everyone is hoping to get this posted soon. ## Rust 2024 review Project board: https://github.com/orgs/rust-lang/projects/43/views/5 None. ### Meta TC: We have tracking issues for the Rust 2024 aspects of every item queued for the edition: https://github.com/rust-lang/rust/issues?q=label%3AA-edition-2024+label%3AC-tracking-issue For each item, we've identified an *owner*. Our most recent update for item owners is here: https://rust-lang.zulipchat.com/#narrow/stream/268952-edition/topic/Owners.20update.202024-04-30 Our motivating priorities are: - Make this edition a success. - Do so without requiring heroics from anyone. - ...or stressing anyone or everyone out. The current timeline to be communicated is: | Date | Version | Edition stage | |------------|---------------|-------------------------| | 2024-06-13 | Release v1.79 | Checking off items..... | | 2024-07-25 | Release v1.80 | Checking off items..... | | 2024-09-05 | Release v1.81 | Checking off items..... | | 2024-10-11 | Branch v1.83 | Go / no go on all items | | 2024-10-17 | Release v1.82 | Rust 2024 nightly beta | | 2025-01-03 | Branch v1.85 | Cut Rust 2024 to beta | | 2025-02-20 | Release v1.85 | Release Rust 2024 | One thing we may need from the project is more scaling of the crater infrastructure and some improvements to the infrastructure. We're looking into this. ### Tracking Issue for Lifetime Capture Rules 2024 (RFC 3498) #117587 **Link:** https://github.com/rust-lang/rust/issues/117587 TC: With the acceptance of RFC 3617 and the great work by CE, this is looking to be in good shape for the edition. ### Reserve gen keyword in 2024 edition for Iterator generators #3513 **Link:** https://github.com/rust-lang/rfcs/pull/3513 TC: With the acceptance of RFC 3513 and the great work by Oli, this is looking to be in good shape for the edition. ### Tracking issue for promoting `!` to a type (RFC 1216) #35121 **Link:** https://github.com/rust-lang/rust/issues/35121 **Link:** https://github.com/rust-lang/rust/pull/123508 TC: With the acceptance of the plan we FCPed in #123508 and the great work by Waffle, this is looking to be in good shape for the edition. ## Nominated RFCs, PRs, and issues ### "Match ergonomics 2024" rfcs#3627 **Link:** https://github.com/rust-lang/rfcs/pull/3627 TC: In the design meeting on 2024-05-15, we discussed Match Ergonomics 2024. We liked what we heard, and people wanted to see this move forward. We did want one change, which was the adoption of *Option 1*: 1. Make `mut x` in inherited patterns an error; convert `mut x` with inherited ref to `&(mut x)` or `&mut (mut x)` in Rust 2021. - This can be extended later backwards compatibly (even in Rust 2024) with the semantics described here (and an explicit syntax). In doing this, we kept desirable properties 2 and 3 below, but (temporarily) sacrificed property 1: 1. You can change `x` to `mut x` to get mutability -- good for users! Writing `let mut x = x` is possible but surprising. 2. There is an explicit form in terms of `&` and `ref` etc for everything you can write with inherited references. 3. Property that, if you have a pattern P without inherited references, e.g., `let &(mut x) = &22` gives `mut x: i32`, and you delete an `&`, then the bindings below become of type `&T` (so e.g. `let mut x = &22`, now `mut x: &i32`). - "weak version" == if both compile, it holds. We filed two concerns on the RFC that both amount to "please change to *Option 1*". Jules, the author, updated the RFC to *Option 1* immediately after the meeting. He also revised to make other clarifications and additions for which we asked. Note also that this RFC is implemented in nightly, including the migration lints. ```rust #![allow(incomplete_features)] #![feature(ref_pat_everywhere)] #![feature(ref_pat_eat_one_layer_2024)] #![feature(mut_preserve_binding_mode_2024)] ``` TC: Do we agree the concerns have been resolved? Josh: I've resolved my concern here. TC: I'll ping Niko about the other one. ### "Use a default lifetime of `'static` in associated consts" rust#125190 **Link:** https://github.com/rust-lang/rust/issues/125190 TC: In the meeting on 2024-05-15, we discussed: - "Bump `elided_lifetimes_in_associated_constant` to deny": https://github.com/rust-lang/rust/pull/124211 We wanted to take some of the churn off of the table, and we agreed that when no other lifetimes are in scope, it seems safe to default to `'static`. tmandry offered to write this up in an issue, and now proposes that we accept: ```rust struct MyType; impl MyType { const FOO: &i32 = &4; } trait Trait { const BAR: &i32; const BAZ: &i32 = &1; } impl Trait for MyType { const BAR: &i32 = Self::FOO; } ``` The checkboxes are here: https://github.com/rust-lang/rust/issues/125190#issuecomment-2116362052 CE has a draft implementation up in: https://github.com/rust-lang/rust/pull/125258 TC: What do we think? Josh: This has the same behavior as non-associated consts? tmandry: Yes, but non-associated consts can't have lifetimes in scope. ### "What are the guarantees around which constants (and callees) in a function get monomorphized?" rust#122301 **Link:** https://github.com/rust-lang/rust/issues/122301 TC: The8472 asks whether this code, which compiles today, can be relied upon: ```rust const fn panic<T>() { struct W<T>(T); impl<T> W<T> { const C: () = panic!(); } W::<T>::C } struct Invoke<T, const N: usize>(T); impl<T, const N: usize> Invoke<T, N> { const C: () = match N { 0 => (), // Not called for `N == 0`, so not monomorphized. _ => panic::<T>(), }; } fn main() { let _x = Invoke::<(), 0>::C; } ``` The8472 notes that this is a useful property and that there are use cases for this in the compiler and the standard library, at least unless or until we adopt something like `const if`: https://github.com/rust-lang/rfcs/issues/3582 RalfJ has pointed out to The8472 that the current behavior might not be intentional and notes: > It's not opt-dependent, but it's also unclear how we want to resolve the opt-dependent issue. Some [proposals](https://github.com/rust-lang/rust/issues/122814#issuecomment-2015090501) involve also walking all items "mentioned" in a const. That would be in direct conflict with your goal here I think. To be clear I think that's a weakness of those proposals. But if that turns out to be the only viable strategy then we'll have to decide what we want more: using `const` tricks to control what gets monomorphized, or not having optimization-dependent errors. > > One crucial part of this construction is that everything involved is generic. If somewhere in the two "branches" you end up calling a monomorphic function, then that may have its constants evaluated even if it is in the "dead" branch -- or it may not, it depends on which functions are deemed cross-crate-inlinable. That's basically what #122814 is about. TC: The question to us is whether we want to guarantee this behavior. What do we think? scottmcm: I feel like this is not something that we want to guaratee without an opt-in. This is sort of a weird attempt to get around the lack of `const match` or `const if`. scottmcm: On the other hand, this is a const item and not a const fn, so we do have to calculate it either way. What I really don't want to guarantee is, within runtime code that may or may not need to be computed at compile time, that `if const_fn() { .. }` does not need to compute `const_fn()`. So don't force us to evaluate `fn foo() -> u32 { if expensive(10) { 123 } else { 456 } }`. scottmcm: So we could have a different rule here, but I'm still inclined not to do so here. tmandry: The rule I'd have in mind here is that if an expression is inside of a const context, either a const item or a `const { .. }`, that we would guarantee it. tmandry: I do want us to have something like `const if`, but if the `if` is in the `const` already... then I don't see a problem here. Looking at the example, I don't see why that should ever evaluate to a `panic!()`. scottmcm: How do we square this with `if false { const { panic!() } }`? tmandry: It would be different from `const { if false { panic!() } }`. tmandry: I propose that we resolve that this is guaranteed. I can't imagine that we'd ever want to evaluate the `panic` branch here. Josh: I'm not seeing the value of forcing the `panic` here. It seems we might be able to guarantee a subset of this. It's not asking for a guarantee that something gets evaluated. It's asking for a guarantee that if we do evaluate it, that it doesn't evaluate branches that aren't monomorphized. scottmcm: Do we have a proposal for what the rule would be? TC: As a next step, let's write out the rule in an issue and nominate that, then maybe FCP it. tmandry: I'll look into doing that, or at least write a comment here. ### "[RFC] externally implementable functions" rfcs#3632 **Link:** https://github.com/rust-lang/rfcs/pull/3632 This RFC is about making this work: ```rust // core::panic: extern impl fn panic_handler(_: &PanicInfo) -> !; // user: impl fn core::panic::panic_handler(panic_info: &PanicInfo) -> ! { eprintln!("panic: {panic_info:?}"); loop {} } ``` This would provide a more general mechanism for something we do repeatedly in custom ways today, e.g. for the `panic_handler`, for the global allocator, etc. There's a companion/alternative RFC 3635: https://github.com/rust-lang/rfcs/pull/3635 It would allow this: ```rust // core::panic: extern static PANIC_HANDLER: fn(_: &PanicInfo) -> !; // user: impl static core::panic::PANIC_HANDLER = |panic_info| { eprintln!("panic: {panic_info:?}"); loop {} }; ``` TC: What do we think? Mara: We have: 1. https://github.com/rust-lang/rfcs/pull/3632 for functions. 2. https://github.com/rust-lang/rfcs/pull/3635 for statics. 3. https://github.com/rust-lang/rfcs/pull/2492 for types. 1 is most ergonomic (and simple). 2 is conceptually simplest. 3 is complicated. Mara: 3 seems stuck forever. (It was closed with rfcbot postpone, years ago.) Josh: I feel like we should consider doing the simple thing first here. I'd love to see externally implementable traits, but I know that will be harder. So I'd be in support of doing the simple thing first here. Also, if we really want to support crates (or std) migrating from a fn to a (single-fn) trait without breaking compatibility, we could. I don't think we're closing any doors here. tmandry: +1. I feel like this would unblock some important use cases. I'm curious how or if we'd adopt this in the standard library. Mara: First, we'd want to use this for how the panic handler and global allocator is implemented, though that would be internal. Then I'd like this for how to control the capture of output in tests. After that, there are others we could consider that would expose it to the public. The first of these could happen before we stabilize it. For stable things, there are often places where people want to customize how the standard library works, e.g. panic behavior. scottmcm: Does the function or static version work better for either of these? Mara: Either one would work. pnkfelix: The RFC doesn't have anything about an `unsafe` keyword. Is there some linker time validation here? Is the only risk here with `no_mangle`? Mara: The compiler will do its normal type checking. pnkfelix: But there are also the link time collisions to consider. Mara: It's the same as for the panic handler. Amanieu: All of the validation is done at compile time when you implement the extern function. So we wouldn't be relying on the linker at all to do any validation. We do this already for the global allocator and panic handler. Amanieu: To me, extern functions seem strictly better than extern statics. Mara: But it works the other way also. They can each implement the other. Amanieu: My preference would be to only support extern traits. There are two levels of unsafe here, whether the trait is unsafe to implement and whether the functions within are unsafe to call. Mara: Then we have four things, not three things: 1. https://github.com/rust-lang/rfcs/pull/3632 for functions 2. https://github.com/rust-lang/rfcs/pull/3635 for statics 3. https://github.com/rust-lang/rfcs/pull/2492 for types 4. Amanieu's proposal for "traits" Mara: All of these solve my problems, but I'd love a direction from the lang team. Josh: Personally, I like the idea of traits being the only thing. But the historic issue there is that it seems more complex. Maybe it could be simplified. But that sounds like maybe a non-trivial delay. It'd be worth seeing the write-up from Amanieu. Amanieu: It's much simpler than you think. Josh: Also, I don't think it's worth doing that just for the ability to put `unsafe` in two places. tmandry: We are solving that problem for regular extern blocks. Why do we need the `impl` keyword here? Can't we just have `extern fn`? Mara: `extern` implies `extern "C"` :( tmandry: It'd be nice if we could solve that. Amanieu: Here's an example of what I'm proposing: ```rust! // core::panic extern trait PanicHandler { fn panic_handler(panic_info: &PanicInfo) -> !; } // user extern impl core::panic::PanicHandler { fn panic_handler(panic_info: &PanicInfo) -> ! { loop {} } } ``` TC: We should cross-check this against the `unsafe extern` RFC we just accepted. pnkfelix: There is probably a path from (1) to (3) or (4). I want to push against blocking here. Josh: +1. TC: Amanieu, can you have an RFC up by next week? Amanieu: Possibly. Josh: If it works like traits, I'd be for it. But this is not quite a trait. I'd raise objections with that path. tmandry: I would suggest this: ```rust! extern "Rust" { fn foo(x: [&'static str]) -> i32; } // or perhaps unsafe extern impl { fn foo(x: [&'static str]) -> i32; } ``` ...and removing the default to `"C"` in the new edition. TC: Suggested next steps: - Write up tmandry's proposal. - Write up Amanieu's proposal. - Cross-check all of these against the goals of the `unsafe extern` RFC (https://github.com/rust-lang/rfcs/pull/3484). scottmcm: I don't want to propose a fifth option, but... can we lean into existing vtables for this? Mara: So, basically `dyn` instead of `impl` for option 3? Josh: Or, it's like option 2, but you're returning a vtable. pnkfelix: Are the proposers of alternative options against option 1? Mara: I think the next steps above make sense. I'm not going to start doing this next week. Can we at least come to a consensus today that this a problem worth fixing? tmandry: I do want to see a solution here. I want to echo what TC said about checking this against the unsafe extern RFC. Josh: We could add that as an open item and address it before stabilization. We don't want to block experimentation here. TC/scottmcm: For experimentation, we can obviously do that ahead af the RFC being approved. Josh: I'm all for unblocking experimentation. But I also think we should accept this RFC, not just punt by calling it an experiment. Amanieu: I'd suggest giving this a week. Consensus seems that we want something like this, but not sure about the exact syntax yet. Tyler: +1. Josh: Mara, do you see this experiment as going in a substantially different direction than option 2 or Amanieu's proposal? Mara: They'll use mostly the same implementation. scottmcm: What pushes me toward doing this as an experiment is being unsure how to pick between option 1 and option 2. Josh: If we only have statics and the vast majority of users use it to store function pointers, I see that as an ergonomics failure. The reverse, using a function to return a data value, doesn't seem as bad, and if lots of people want to use it for static data we can always add the static version or something else. *Consensus*: We do see this as an important problem. We're approving this as an experiment with Josh as the liaison. (The meeting ended here.) --- ### "Tracking issue for function attribute `#[coverage]`" rust#84605 **Link:** https://github.com/rust-lang/rust/issues/84605 TC: This is about stabilizing a `#[coverage(off)]` attribute to exclude items from `-Z instrument-coverage`. Josh proposed FCP merge and nominated this for us. > Let's go ahead and see if we have consensus to stabilize this _other_ than the potential issue of applying it automatically to nested functions or inlined functions. > > My proposal would be that `coverage(off)` should automatically apply to functions (and closures) nested inside the function in question, but that it _shouldn't_ automatically apply to inlined functions. > > Rationale: putting `#[coverage(off)]` on a function should apply to everything inside it for convenience, but things it _calls_ might still want coverage for other reasons. I'd propose that if we want something that recursively disables coverage, that should be an additional attribute. > > However, this is a loosely held position, and I'd love to see a good argument / use case for also disabling it on inlined functions. Correspondingly, there are two open questions about applying this automatically to nested functions and to inlined functions. Checkboxes are here: https://github.com/rust-lang/rust/issues/84605#issuecomment-1937373497 TC: What do we think? ### "Stabilize `extended_varargs_abi_support`" rust#116161 **Link:** https://github.com/rust-lang/rust/pull/116161 TC: This stabilization was nominated for us, with pnkfelix commenting: > Just to add on to @cjgillot 's comment above: @wesleywiser and I could not remember earlier today whether T-lang _wants_ to own FCP'ing changes like this that are restricted to extending the set of calling-conventions (i.e. the `conv` in `extern "conv" fn foo(...)`), which is largely a detail about what platforms one is interoperating with, and not about changing the expressiveness of the Rust language as a whole in the abstract. > > (My own gut reaction is that T-compiler is a more natural owner for this than T-lang, but I wasn't certain and so it seems best to let the nomination stand and let the two teams duke it out.) TC: What do we think about 1) this stabilization, and 2) whether we want to own this? ### "Don't make statement nonterminals match pattern nonterminals" rust#120221 **Link:** https://github.com/rust-lang/rust/pull/120221 TC: CE handed this one to us, since it changes the contract of macro matchers. Here's the code that does not work today that we would make work: ```rust macro_rules! m { ($pat:pat) => {}; ($stmt:stmt) => {}; } macro_rules! m2 { ($stmt:stmt) => { m! { $stmt } //~^ ERROR expected pattern }; } m2! { let x = 1 } ``` This code does not work because we consider `:stmt` to be a possible `:pat` even though we then always reject it later in the process. By saying that `:stmt` cannot be a `:pat`, we make this code work. We discussed this in the meeting on 2024-03-27: > CE: Right now the tokens that a macro matcher may begin with is a stable guarantee. We are relaxing the assumption that pattern matchers may begin with statement metavariables ($var whose type is stmt), because when we actually try to *parse* such a pattern, we are always guaranteed to fail. This only allows more code to compile, and would only break future code if we specifically wanted to begin patterns with *statement metavariable*. > > scottmcm: I agree that it's weird to allow a `:stmt` in a pattern, so am happy to say we won't. Let's see what others think, since this conversation was in a sparsely-attended triage meeting: > > scottmcm: The other thing we explored was what it would take to make this actually work, since you can actually put an `:expr` into a pattern. But CE argued that we don't actually like that that works, it's just something we're stuck with because people used it before `:literal` was available, which seems fair. TC: What do we think? ### "Initial support for auto traits with default bounds" rust#120706 **Link:** https://github.com/rust-lang/rust/pull/120706 TC: This is related to this MCP about a path toward async drop and scoped tasks: https://github.com/rust-lang/compiler-team/issues/727 TC: petrochenkov gives some background: > So, what are the goals here: > > * We want to have a possibility to add new auto traits that are added to _all_ bound lists by default on the current edition. The examples of such traits could be `Leak`, `Move`, `SyncDrop` or something else, it doesn't matter much right now. The desired behavior is similar to the current `Sized` trait. Such behavior is required for introducing `!Leak` or `!SyncDrop` types in a backward compatible way. (Both `Leak` and `SyncDrop` are likely necessary for properly supporting libraries for scoped async tasks and structured concurrency.) > * It's not clear whether it can be done backward compatibly and without significant perf regressions, but that's exactly what we want to find out. Right now we encounter some cycle errors and exponential blow ups in the trait solver, but there's a chance that they are fixable with the new solver. > * Then we want to land the change into rustc under an option, so it becomes available in bootstrap compiler. Then we'll be able to do standard library experiments with the aforementioned traits without adding hundreds of `#[cfg(not(bootstrap))]`s. > * Based on the experiments, we can come up with some scheme for the next edition, in which such bounds are added more conservatively. > * Relevant blog posts - https://without.boats/blog/changing-the-rules-of-rust/, https://without.boats/blog/follow-up-to-changing-the-rules-of-rust/ and https://without.boats/blog/generic-trait-methods-and-new-auto-traits/, https://without.boats/blog/the-scoped-task-trilemma/ > * Larger compiler team MCP including this feature - [MCP: Low level components for async drop compiler-team#727](https://github.com/rust-lang/compiler-team/issues/727), it gives some more context We discussed this in the async WG on 2024-03-25 and commented: > This is interesting work, but there's a lot to review here. We'd be particularly interested in seeing something in the way of a design document here, specifically e.g. with respect to when these bounds are added and when they are not, and how they interact with the `?` bounds. Seeing the algorithm spelled out in words and in theory would definitely help us understand this. The best place to put this may be in the [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide). The question here is whether we want to charter this as an experiment. ### "Let's `#[expect]` some lints: Stabilize `lint_reasons` (RFC 2383) " rust#120924 **Link:** https://github.com/rust-lang/rust/pull/120924 TC: Since the last time this was proposed for stabilization, various unresolved questions have now been resolved, so this is being proposed again. We're talking about this: ```rust #![feature(lint_reasons)] fn main() { #[deny(unused_variables, reason = "unused variables, should be removed")] let unused = "How much wood would a woodchuck chuck?"; } error: unused variable: `unused` --> src/main.rs:5:9 | 5 | let unused = "How much wood would a woodchuck chuck?"; | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused` | = note: unused variables, should be removed note: the lint level is defined here --> src/main.rs:4:12 | 4 | #[deny(unused_variables, reason = "unused variables, should be removed")] | ^^^^^^^^^^^^^^^^ ``` And this: ```rust #![feature(lint_reasons)] fn main() { #[expect(unused_variables, reason = "WIP, I'll use this value later")] let message = "How much wood would a woodchuck chuck?"; #[expect(unused_variables, reason = "is this unused?")] let answer = "about 700 pounds"; println!("A: {answer}") } warning: this lint expectation is unfulfilled --> src/main.rs:4:14 | 6 | #[expect(unused_variables, reason = "is this unused?")] | ^^^^^^^^^^^^^^^^ | = note: `#[warn(unfulfilled_lint_expectations)]` on by default = note: is this unused? ``` On 2024-03-15, tmandry proposed FCP merge, and nikomatsakis is also +1. This needs one more +1 to go into FCP. What do we think? ### "Support ?Trait bounds in supertraits and dyn Trait under a feature gate" rust#121676 **Link:** https://github.com/rust-lang/rust/pull/121676 TC: This is related to this MCP about a path toward async drop and scoped tasks: https://github.com/rust-lang/compiler-team/issues/727 TC: petrochenkov gives some background: > Summary: > > * [Initial support for auto traits with default bounds #120706](https://github.com/rust-lang/rust/pull/120706) introduces a way to add new auto traits that are appended to all bound lists by default, similarly to existing `Sized`. Such traits may include `Leak`, `SyncDrop` or similar, see [Initial support for auto traits with default bounds #120706 (comment)](https://github.com/rust-lang/rust/pull/120706#issuecomment-1934006762) for more detailed motivation. > * To opt out from bounds added by default the `?Trait` syntax is used, but such "maybe" bounds are not supported in some contexts like supertrait lists and `dyn Trait + ...` lists, because `Sized` is not added by default in those context. > * This PR adds a feature for supporting `trait Trait1: ?Trait2`, `dyn Trait1 + ?Trait2` and also multiple maybe bounds in the same list `?Trait1 + ?Trait2`, because the new traits need to be added by default in those contexts too, and `?Sized + ?Leak` may also make sense. > * We need this to be available in bootstrap compiler, to make experiments on standard library without adding too many `#[cfg(not(bootstrap))]`s > * Larger compiler team MCP including this feature - [MCP: Low level components for async drop compiler-team#727](https://github.com/rust-lang/compiler-team/issues/727), it gives some more context TC: The question here is whether we want to charter this as an experiment. ### "Elaborate on the invariants for references-to-slices" rust#121965 **Link:** https://github.com/rust-lang/rust/pull/121965 TC: scottmcm filed this issue and explains: > The length limit on slices is clearly a safety invariant, and I'd like it to also be a validity invariant. With [function parameter metadata](https://discourse.llvm.org/t/rfc-metadata-attachments-for-function-arguments/76420?u=scottmcm) making progress in LLVM, I'd really like to be able to use it when `&[_]` is passed as a scalar pair, in particular. > > The documentation for references is cagey about what exactly is a validity invariant, so for now just elaborate on the consequences of the existing safety rules on slices -- the length restriction follows from the `size_of_val` restriction -- as a way to help discourage people from trying to violate them. > > I also made the existing warning stronger, since I'm fairly sure it's already UB to violate at least the "references must be non-null" rule, rather than it just being that it "might be UB in the future". Then joboet nominated this for us with: > Given that `slice::from_raw_parts` already states that "the total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`" and that its behaviour is undefined otherwise, I'd say that this is entirely uncontroversial. Still, I'd appreciate some team sign-off on this, I think this concerns lang? RalfJ thinks this should probably be a dual T-lang / T-opsem FCP. TC: What do we think? ### "`#![crate_name = EXPR]` semantically allows `EXPR` to be a macro call but otherwise mostly ignores it" rust#122001 **Link:** https://github.com/rust-lang/rust/issues/122001 TC: In previous stable versions of Rust, `#![crate_name = EXPR]` worked. That is, within `EXPR` we expanded and then used macro calls such as `concat`. However, due to: https://github.com/rust-lang/rust/pull/117584 ...we broke this, and then we shipped it in stable Rust v1.77. Except, we only half broke it. It doesn't work, but neither is it a hard error. It just quietly ignores the result. We discussed this in the meeting on 2024-03-27 and agreed this was the worst of all worlds, and so we should at a minimum break it completely, and then we could always later decide to relax the hard error and make it work again by reverting #117584. On that basis, scottmcm proposed FCP merge. TC: What do we think? ### "Assert that the first `assert!` expression is `bool`" rust#122661 **Link:** https://github.com/rust-lang/rust/pull/122661 TC: estebank describes this issue for us: > In the desugaring of `assert!` in 2024 edition, assign the condition expression to a `bool` biding in order to provide better type errors when passed the wrong thing. > > The span will point only at the expression, and not the whole `assert!` invocation. > ``` error[E0308]: mismatched types --> $DIR/issue-14091.rs:2:13 | LL | assert!(1,1); | ^ expected `bool`, found integer ``` > > We no longer mention the expression needing to implement the `Not` trait. > ``` error[E0308]: mismatched types --> $DIR/issue-14091-2.rs:15:13 | LL | assert!(x, x); | ^ expected `bool`, found `BytePos` ``` > > In <=2021 edition, we still accept any type that implements `Not<Output = bool>`. TC: And pnkfelix nominates this for us: > At the very least, we might need to tie such a change to an edition. > > I am not certain whether this decision would be a T-lang matter or a T-libs-api one. I'll nominate for T-lang for now. > > (Namely: The question is whether we can start enforcing a rule that the first expression to `assert!` must be of bool type, which is how the [macro is documented](https://doc.rust-lang.org/std/macro.assert.html), but its current behavior is a little bit more general, as demonstrated in my [prior comment](https://github.com/rust-lang/rust/pull/122661#issuecomment-2004197554)) > > ... > > There _is_ a design space here. E.g. one set of options is: > > 1. (stable Rust behavior): in all editions, support arbitrary `impl Not<Output=bool>` for first parameter to `assert!`; > 2. in edition >= 2024, support _just_ `Deref<Target=bool>` for first parameter to `assert!` (e.g. by expanding to `let x: &bool = &$expr;`), or > 3. (this PR): in edition >= 2024, support _just_ `bool` for first parameter to `assert!`. > > (And then there's variations thereof about how to handle editions < 2024, but that's a separate debate IMO.) TC: What do we think? ### "Emit a warning if a `match` is too complex" rust#122685 **Link:** https://github.com/rust-lang/rust/pull/122685 TC: Nadri nominates this for us and describes the situation: > Dear T-lang, this PR adds a warning that cannot be silenced, triggered when a match takes a really long time to analyze (in the order of seconds). This is to help users figure out what's taking so long and fix it. > > We _could_ make the limit configurable or the warning `allow`able. I argue that's not necessary because [crater](https://github.com/rust-lang/rust/pull/121979#issuecomment-2003089646) showed zero regressions with the current limit, and it's be pretty easy in general to split up a `match` into smaller `match`es to avoid blowup. > > We're still figuring out the exact limit, but does the team approve in principle? (As an aside, awhile back someone [showed](https://niedzejkob.p4.team/rust-np/) how to [lower](https://github.com/NieDzejkob/rustc-sat) SAT to exhaustiveness checking with `match`. Probably that would hit this limit.) TC: What do we think? ### "Policy for lint expansions" rust#122759 **Link:** https://github.com/rust-lang/rust/issues/122759 TC: In the call on 2024-03-13, we discussed this issue raised by tmandry: "Fallout from expansion of redundant import checking" https://github.com/rust-lang/rust/issues/121708 During the call, the thoughts expressed included: - We don't want to create a perverse incentive for people to expand existing lints rather than to create new ones where appropriate just because there's less process for expanding the meaning of an existing lint. - It would be good if potentially-disruptive expansions of an existing lint either: - Had a machine-applicable fix. - Or had a new name. - We don't want to require a new lint name for each expansion. - We don't want to require a crater run for each change to a lint. - There are two ways to prevent disruption worth exploring: - Prevent potentially-disruptive changes from hitting master. - Respond quickly to early indications of disruption once the changes hit master. - Compiler maintainers have a sense of what might be disruptive and are cautious to avoid it. It may be OK to have a policy that is not perfectly measurable. TC: tmandry volunteered to draft a policy proposal. He's now written up this proposal in this issue. > ## Background > > When a lint is expanded to include many new cases, it adds significant complexity to the rollout of a toolchain to large codebases. Maintainers of these codebases are stuck with the choice of > > 1. Disabling the existing lint while the toolchain is updated and new cases are fixed > 2. Fixing cases manually and updating the toolchain immediately > > Both of these come with the problem of _racing_ with other developers in a codebase who may land new code which triggers the expanded lint in a new compiler, but does _not_ trigger the lint in an old compiler. > > While it would be nice to solve this "raciness" once and for all, there are other considerations at play. Instead, we propose to support these users by either providing them with a new lint name to temporarily opt out of _OR_ a machine-applicable fix which eases the pain of any races which might occur. > > Note that this requirement only applies to _significant_ lint expansions as measured by crater. > > ## Policy > > When an existing lint is expanded to include many new cases, we must provide either: > > 1. A new lint name under the existing group, so that users may opt out of the expansion at least temporarily, or > 2. A MachineApplicable fix for the lint. > > Exceptions to this policy may be made via Language Team FCP. > > Here, we define "many new cases" as impacting more than 5% of the top-1000 crates on crates.io. This can be measured by counting the number of regressions from a crater run like the one below. > > A crater run is not required before landing for every lint expansion. Reviewers should use their best judgment to decide if one is required. However, if a lint expansion lands that violates this requirement, or is strongly suspected to violate this requirement based on other impact, it should be reverted. > > #### Crater command > > To measure the impact of a lint as defined by this policy, you can use the following crater command: > > `@craterbot run name=<name> start=master#<hash1>+rustflags=-D<lint_name> end=master#<hash2>+rustflags=-D<lint_name> crates=top-1000 mode=check-only p=1` > > See the [crater docs](https://github.com/rust-lang/crater/blob/master/docs/bot-usage.md#tutorial-creating-an-experiment-for-a-pr) for more information. TC: What do we think? ### "Raw Keywords" rfcs#3098 **Link:** https://github.com/rust-lang/rfcs/pull/3098 TC: We've at various times discussed that we had earlier decided that if we wanted to use a new keyword within an edition, we would write it as `k#keyword`, and for that reason, we prefer to not speculatively reserve keywords ahead of an edition (except, perhaps, when it's clear we plan to use it in the near future). TC: Somewhat amusingly, however, we never in fact accepted that RFC. Back in 2021, we accepted scottmcm's proposal to **cancel**: > We discussed this RFC again in the lang team triage meeting today. > > For the short-term goal of the reservation for the edition, we'll be moving forward on #3101 instead. As such, we wanted to leave more time for conversations about this one, and maybe use crater results from 3101 to make design changes, > > @rfcbot cancel Instead we accepted RFC 3101 that reserved `ident#foo`, `ident"foo"`, `ident'f'`, and `ident#123` starting in the 2023 edition. Reading through the history, here's what I see: - What do we want to do about Rust 2015 and Rust 2018? It's a breaking change to add this there. Is this OK? Do we want to do a crater run on this? - Would we have the stomach to actually do this? It's one thing to *say* that if we wanted to use a new keyword within an edition, we'd write `k#keyword`, but it's another to actually do it in the face of certain criticism about that being e.g. unergonomic. Would we follow through? TC: What do we think? ### "Tracking issue for the `start` feature" rust#29633 **Link:** https://github.com/rust-lang/rust/issues/29633 TC: Nils proposes to us that we delete the unstable `#[start]` attribute: > I think this issue should be closed and `#[start]` should be deleted. It's nothing but an accidentally leaked implementation detail that's a not very useful mix between "portable" entrypoint logic and bad abstraction. > > I think the way the stable user-facing entrypoint should work (and works today on stable) is pretty simple: > > * `std`-using cross-platform programs should use `fn main()`. the compiler, together with `std`, will then ensure that code ends up at `main` (by having a platform-specific entrypoint that gets directed through `lang_start` in `std` to `main` - but that's just an implementation detail) > * `no_std` platform-specific programs should use `#![no_main]` and define their own platform-specific entrypoint symbol with `#[no_mangle]`, like `main`, `_start`, `WinMain` or `my_embedded_platform_wants_to_start_here`. most of them only support a single platform anyways, and need cfg for the different platform's ways of passing arguments or other things _anyways_ > > `#[start]` is in a super weird position of being neither of those two. It tries to pretend that it's cross-platform, but its signature is a total lie. Those arguments are just stubbed out to zero on Windows, for example. It also only handles the platform-specific entrypoints for a few platforms that are supported by `std`, like Windows or Unix-likes. `my_embedded_platform_wants_to_start_here` can't use it, and neither could a libc-less Linux program. So we have an attribute that only works in some cases anyways, that has a signature that's a total lie (and a signature that, as I might want to add, has changed recently, and that I definitely would not be comfortable giving _any_ stability guarantees on), and where there's a pretty easy way to get things working without it in the first place. > > Note that this feature has **not** been RFCed in the first place. TC: What do we think? ### "Stabilize `anonymous_lifetime_in_impl_trait`" rust#107378 **Link:** https://github.com/rust-lang/rust/pull/107378 TC: We unnominated this back in October 2023 as more analysis seemed to be needed. Since then, nikomatsakis and tmandry have posted substantive analysis that it seems we should discuss. ### "#[cold] on match arms" rust#120193 **Link:** https://github.com/rust-lang/rust/pull/120193 TC: Apparently our unstable `likely` and `unlikely` intrinsics don't work. There's a proposal to do some work on fixing that and stabilizing a solution here. The nominated question is whether we want to charter this as an experiment. ### "add float semantics RFC" rfcs#3514 **Link:** https://github.com/rust-lang/rfcs/pull/3514 TC: In addition to documenting the current behavior carefully, this RFC (per RalfJ)... > says we should allow float operations in `const fn`, which is currently not stable. This is a somewhat profound decision since it is the first non-deterministic operation we stably allow in `const fn`. (We already allow those operations in `const`/`static` initializers.) TC: What do we think? tmandry proposed this for FCP merge back in October 2023. ### "Tracking Issue for unicode and escape codes in literals" rust#116907 **Link:** https://github.com/rust-lang/rust/issues/116907 TC: nnethercote has implemented most of RFC 3349 ("Mixed UTF-8 literals") and, based on implementation experience, argues that the remainder of the RFC should not be implemented: > I have a partial implementation of this RFC working locally (EDIT: now at #120286). The RFC proposes five changes to literal syntax. I think three of them are good, and two of them aren't necessary. TC: What do we think? ### "Proposal: Remove `i128`/`u128` from the `improper_ctypes` lint" lang-team#255 **Link:** https://github.com/rust-lang/lang-team/issues/255 TC: Trevor Gross describes the situation: > For a while, Rust's 128-bit integer types have been incompatible with those from C. The original issue is here [rust-lang/rust#54341](https://github.com/rust-lang/rust/issues/54341), with some more concise background information at the MCP here [rust-lang/compiler-team#683](https://github.com/rust-lang/compiler-team/issues/683) > > The current Beta of 1.77 will have [rust-lang/rust#116672](https://github.com/rust-lang/rust/pull/116672), which manually sets the alignment of `i128` to make it ABI-compliant with any version of LLVM (`clang` does something similar now). 1.78 will have LLVM18 as the vendored version which fixes the source of this error. > > Proposal: now that we are ABI-compliant, do not raise `improper_ctypes` on our 128-bit integers. I did some testing with abi-cafe and a more isolated https://github.com/tgross35/quick-abi-check during the time https://reviews.llvm.org/D86310 was being worked on, and verified everything lines up. (It would be great to have some fork of abi-cafe in tree, but that is a separate discussion.) > > @joshtriplett mentioned that changing this lint needs a lang FCP https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm/topic/LLVM.20alignment.20of.20i128/near/398422037. cc @maurer > > Reference change from when I was testing [rust-lang/rust@c742908](https://github.com/rust-lang/rust/commit/c742908c4b9abde264b8c5e9663e31c649a47f2f) TC: Josh nominates this for our discussion. What do we think? ### "`is` operator for pattern-matching and binding" rfcs#3573 **Link:** https://github.com/rust-lang/rfcs/pull/3573 TC: Josh proposes for us that we should accept: ```rust if an_option is Some(x) && x > 3 { println!("{x}"); } ``` And: ```rust func(x is Some(y) && y > 3); ``` TC: The main topic discussed in the issue thread so far has been the degree to which Rust should have "two ways to do things". Probably the more interesting issue is how the binding and drop scopes for this should work. TC: In the 2024-02-21 meeting (with limited attendance), we discussed how we should prioritize stabilizing let chains, and tmandry suggested we may want to allow those to settle first. TC: What do we think, as a gut check? ### "Unsafe fields" rfcs#3458 **Link:** https://github.com/rust-lang/rfcs/pull/3458 TC: Nearly ten years ago, on 2014-10-09, pnkfelix proposed unsafe fields in RFC 381: https://github.com/rust-lang/rfcs/issues/381 On 2017-05-04, Niko commented: > I am pretty strongly in favor of unsafe fields at this point. The only thing that holds me back is some desire to think a bit more about the "unsafe" model more generally. Then, in 2023, Jacob Pratt refreshed this proposal with RFC 3458. It proposes that: > Fields may be declared `unsafe`. Unsafe fields may only be mutated (excluding interior mutability) or initialized in an unsafe context. Reading the value of an unsafe field may occur in either safe or unsafe contexts. An unsafe field may be relied upon as a safety invariant in other unsafe code. E.g.: ```rust struct Foo { safe_field: u32, /// Safety: Value must be an odd number. unsafe unsafe_field: u32, } // Unsafe field initialization requires an `unsafe` block. // Safety: `unsafe_field` is odd. let mut foo = unsafe { Foo { safe_field: 0, unsafe_field: 1, } }; ``` On 2024-05-21, Niko nominated this for us: > I'd like to nominate this RFC for discussion. I've not read the details of the thread but I think the concept of unsafe fields is something that comes up continuously and some version of it is worth doing. TC: What do we think? ### "RFC: Allow symbol re-export in cdylib crate from linked staticlib" rfcs#3556 **Link:** https://github.com/rust-lang/rfcs/pull/3556 TC: This seems to be about making the following work: ```rust // kind is optional if it's been specified elsewhere, e.g. via the `-l` flag to rustc #[link(name="ext", kind="static")] extern { #[no_mangle] pub fn foo(); #[no_mangle] pub static bar: std::ffi::c_int; } ``` There are apparently use cases for this. What's interesting is that apparently it already does, but we issue a warning that is wrong: ```rust warning: `#[no_mangle]` has no effect on a foreign function --> src/lib.rs:21:5 | 21 | #[no_mangle] | ^^^^^^^^^^^^ help: remove this attribute 22 | pub fn foo_rfc3556_pub_with_no_mangle(); | ---------------------------------------- foreign function | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: symbol names in extern blocks are not mangled ``` TC: One of the author's asks of us is that we don't make this into a hard error (e.g. with the new edition). TC: What do we think? ### "[RFC] externally implementable functions" rfcs#3632 **Link:** https://github.com/rust-lang/rfcs/pull/3632 This RFC is about making this work: ```rust // core::panic: extern impl fn panic_handler(_: &PanicInfo) -> !; // user: impl fn core::panic::panic_handler(panic_info: &PanicInfo) -> ! { eprintln!("panic: {panic_info:?}"); loop {} } ``` This would provide a more general mechanism for something we do repeatedly in custom ways today, e.g. for the `panic_handler`, for the global allocator, etc. There's a companion/alternative RFC 3635: https://github.com/rust-lang/rfcs/pull/3635 It would allow this: ```rust // core::panic: extern static PANIC_HANDLER: fn(_: &PanicInfo) -> !; // user: impl static core::panic::PANIC_HANDLER = |panic_info| { eprintln!("panic: {panic_info:?}"); loop {} }; ``` TC: What do we think? ### "Better errors with bad/missing identifiers in MBEs" rust#118939 **Link:** https://github.com/rust-lang/rust/pull/118939 TC: The idea here seems to be to improve some diagnostics around `macro_rules`, but this seems to be done by way of reserving the `macro_rules` token more widely, which is a breaking change. Petrochenkov has objected to it on that basis, given that reserving `macro_rules` minimally has been the intention since we hope it will one day disappear in favor of `macro`. What do we think? ### "Uplift `clippy::invalid_null_ptr_usage` lint" rust#119220 **Link:** https://github.com/rust-lang/rust/pull/119220 TC: Urgau proposes this for us: > This PR aims at uplifting the `clippy::invalid_null_ptr_usage` lint into rustc, this is similar to the [`clippy::invalid_utf8_in_unchecked` uplift](https://github.com/rust-lang/rust/pull/111543) a few months ago, in the sense that those two lints lint on invalid parameter(s), here a null pointer where it is unexpected and UB to pass one. > > ## `invalid_null_ptr_usages` > > (deny-by-default) > > The `invalid_null_ptr_usages` lint checks for invalid usage of null pointers. > > ### Example > ```rust // Undefined behavior unsafe { std::slice::from_raw_parts(ptr::null(), 0); } // Not Undefined behavior unsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); } ``` > > Produces: > ``` error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused, consider using a dangling pointer instead --> $DIR/invalid_null_ptr_usages.rs:14:23 | LL | let _: &[usize] = std::slice::from_raw_parts(ptr::null(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ | | | help: use a dangling pointer instead: `core::ptr::NonNull::dangling().as_ptr()` ``` > > ### Explanation > > Calling methods who's safety invariants requires non-null pointer with a null pointer is undefined behavior. > > The lint use a list of functions to know which functions and arguments to checks, this could be improved in the future with a rustc attribute, or maybe even with a `#[diagnostic]` attribute. TC: What do we think? ### "Stop skewing inference in ?'s desugaring" rust#122412 **Link:** https://github.com/rust-lang/rust/pull/122412 TC: Waffle nominates this breaking change for us: > This changes `expr?`'s desugaring like so (simplified, see code for more info): > > ```rust > // old > match expr { > Ok(val) => val, > Err(err) => return Err(err), > } > > // new > match expr { > Ok(val) => val, > Err(err) => core::convert::absurd(return Err(err)), > } > > // core::convert > pub const fn absurd<T>(x: !) -> T { x } > ``` > > This prevents `!` from the `return` from skewing inference: > > ```rust > // previously: ok (never type spontaneous decay skews inference, `T = ()`) > // with this pr: can't infer the type for `T` > Err(())?; > ``` We discussed this on 2024-03-20. On the one hand, people were hesitant to block incremental progress, but on the other, people were hesitant to add a special case if we could address a more general case. There was, I would say, appetite for taking a bigger bite here, but people were uncertain if there were any bigger bites that were feasible other than those discussed to support the never type generally, such as disabling fallback to `()`. In terms of next steps, we wanted to see an answer about the pros and cons of doing this for `return` generally, which @WaffleLapkin has now [answered](https://github.com/rust-lang/rust/pull/122412#issuecomment-2010480706): > > it made me wonder whether it would be feasible to change return in general to be a free type variable instead of `!`? > > @scottmcm I'm not sure. I don't think it's unfeasible, but it sure is harder than this. > > The issues are: > > * Need to add fallback for those type variables too, so that `return;` works > * `{ return; }` (which is currently `!` even though there is `;`) needs to be special cased in a different way > * Will break strictly more things > > I'm not sure if this is a good idea or not. It's kinda weird. ...and we wanted to see the results of the crater run that we know that @WaffleLapkin is working to make happen. When taking this back up, in addition to those details, we wanted to specifically consider how this incremental step may be addressing known footguns with unsafe code such as that in: https://github.com/rust-lang/rust/issues/51125 TC: What do we think? ### "panic in a no-unwind function leads to not dropping local variables" rust#123231 **Link:** https://github.com/rust-lang/rust/issues/123231 TC: RalfJ nominates this for us. Consider this code: ```rust #![feature(c_unwind)] struct Noise; impl Drop for Noise { fn drop(&mut self) { eprintln!("Noisy Drop"); } } extern "C" fn test() { let _val = Noise; panic!("heyho"); } fn main() { test(); } ``` It doesn't print anything. Should it? ### "Parse unsafe attributes" rust#124214 **Link:** https://github.com/rust-lang/rust/pull/124214 TC: We accepted RFC 3325 for unsafe attributes, e.g. `#[unsafe(no_mangle)]`. There's now an implementation of this, and for the edition, we need to make a final decision on which attributes are actually unsafe. The current list is: - `no_mangle` - `link_section` - `export_name` There's been discussion about `link` and `link_ordinal` also. In the meeting on 2024-05-15, pnkfelix took on ownership of ensuring that the final list is correct. ### "Lang discussion: Item-level `const {}` blocks, and `const { assert!(...) }`" lang-team#251 **Link:** https://github.com/rust-lang/lang-team/issues/251 TC: This issue was raised due to discussion in a T-libs-api call. Josh gives the context: > In discussion of [rust-lang/libs-team#325](https://github.com/rust-lang/libs-team/issues/325) (a proposal for a compile-time assert macro), the idea came up to allow `const {}` blocks at item level, and then have people use `const { assert!(...) }`. > > @rust-lang/libs-api would like some guidance from @rust-lang/lang about whether lang is open to toplevel `const { ... }` blocks like this, which would influence whether we want to add a compile-time assert macro, as well as what we want to call it (e.g. `static_assert!` vs `const_assert!` vs some other name). > > Filing this issue to discuss in a lang meeting. This issue is _not_ seeking any hard commitment to add such a construct, just doing a temperature check. CAD97 noted: > To ensure that it's noted: if both item and expression `const` blocks are valid in the same position (i.e. in statement position), a rule to disambiguate would be needed (like for statement versus expression `if`-`else`). IMO it would be quite unfortunate for item-level `const` blocks to be evaluated pre-mono if that same `const` block but statement-level would be evaluated post-mono. > > Additionally: since `const { assert!(...) }` is post-mono (due to using the generic context), it's potentially desirable to push people towards using `const _: () = assert!(...);` (which is pre-mono) whenever possible (not capturing generics). TC: What do we think? ### "Add lint against function pointer comparisons" rust#118833 **Link:** https://github.com/rust-lang/rust/pull/118833 TC: In the 2024-01-03 call, we developed a tentative consensus to lint against direct function pointer comparison and to push people toward using `ptr::fn_addr_eq`. We decided to ask T-libs-api to add this. There's now an open proposal for that here: https://github.com/rust-lang/libs-team/issues/323 One question that has come up is whether we would expect this to work like `ptr::addr_eq` and have separate generic parameters, e.g.: ```rust /// Compares the *addresses* of the two pointers for equality, /// ignoring any metadata in fat pointers. /// /// If the arguments are thin pointers of the same type, /// then this is the same as [`eq`]. pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool { .. } ``` Or whether we would prefer that `fn_addr_eq` enforced type equality of the function pointers. Since we're the ones asking for this, we probably want to develop a consensus here. We discussed this in the call on 2024-01-10, then we opened a Zulip thread: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Signature.20of.20.60ptr.3A.3Afn_addr_eq.60 TC: On this subject, scottmcm raised this point, with which pnkfelix seemed to concur: > I do feel like if I saw code that had `fn1.addr() == fn2.addr()` (if `FnPtr` were stabilized), I'd write a comment saying "isn't that what `fn_addr_eq` is for?" > > If the answer ends up being "no, actually, because I have different types", that feels unfortunate even if it's rare. > > (Like how `addr_eq(a, b)` is nice even if with strict provenance I could write `a.addr() == b.addr()` anyway.) TC: scottmcm also asserted confidence that allowing mixed-type pointer comparisons is correct for `ptr::addr_eq` since comparing the addresses of `*const T`, `*const [T; N]`, and `*const [T]` are all reasonable. I pointed out that, if that's reasonable, then `ptr::fn_addr_eq` is the higher-ranked version of that, since for the same use cases, it could be reasonable to compare function pointers that return those three different things or accept them as arguments. TC: Adding to that, scottmcm noted that comparing addresses despite lifetime differences is also compelling, e.g. comparing `fn(Box<T>) -> &'static mut T` with `for<'a> fn(Box<T>) -> &'a mut T`. TC: Other alternatives we considered were not stabilizing `ptr::fn_addr_eq` at all and instead stabilizing `FnPtr` so people could write `ptr::addr_eq(fn1.addr(), fn2.addr())`, or expecting that people would write instead `fn1 as *const () == fn2 as *const ()`. TC: Recently CAD97 raised an interesting alternative: > From the precedent of `ptr::eq` and `ptr::addr_eq`, I'd expect a "`ptr::fn_eq`" to have one generic type and a "`ptr::fn_addr_eq`" to have two. Even if `ptr::fn_eq`'s implementation is just an address comparison, it still serves as a documentation point to call out the potential pitfalls with comparing function pointers. TC: What do we think? --- TC: Separately, on the 2024-01-10 call, we discussed some interest use cases for function pointer comparison, especially when it's indirected through `PartialEq`. We had earlier said we didn't want to lint when such comparisons were indirected through generics, but we did address the non-generic case of simply composing such comparisons. One example of how this is used is in the standard library, in `Waker::will_wake`: https://doc.rust-lang.org/core/task/struct.Waker.html#method.will_wake It's comparing multiple function pointers via a `#[derive(PartialEq)]` on the `RawWakerVTable`. We decided on 2024-01-01 that this case was interesting and we wanted to think about it further. We opened a discussion thread about this: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Function.20pointer.20comparison.20and.20.60PartialEq.60 Since then, another interesting use case in the standard library was raised, in the formatting machinery: https://doc.rust-lang.org/src/core/fmt/rt.rs.html What do we think about these, and would we lint on derived `PartialEq` cases like these or no? ### "Implement lint against unexpected unary precedence" rust#121364 **Link:** https://github.com/rust-lang/rust/pull/121364 TC: The proposal is to lint against: ```rust -2.pow(2); // Equals -4. ``` These would instead be written: ```rust -(2.pow(2)); // Equals -4. ``` TC: This is a subset of: https://github.com/rust-lang/rust/pull/117161 ...which is also nominated. Whereas the #117161 proposal is to lint on both binary op and unary op cases, this proposal is to lint only on unary op cases. The proposal for this subset came out a discussion with scottmcm. TC: What do we think? ### "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 (e.g. `!`, `*`, `&`)? ### "Should Rust still ignore SIGPIPE by default?" rust#62569 **Link:** https://github.com/rust-lang/rust/issues/62569 TC: Prior to `main()` being executed, the Rust startup code makes a syscall to change the handling of `SIGPIPE`. Many believe that this is wrong thing for a low-level language like Rust to do, because 1) it makes it impossible to recover what the original value was, and 2) means things like `seccomp` filters must be adjusted for this. It's also just, in a practical sense, wrong for most CLI applications. This seems to have been added back when Rust had green threads and then forgotten about. But it's been an ongoing footgun. Making a celebrity appearance, Rich Felker, the author of MUSL libc, notes: > As long as Rust is changing signal dispositions inside init code in a way that the application cannot suppress or undo, it is _fundamentally unusable to implement standard unix utilities that run child processes_ or anything that needs to preserve the signal dispositions it was invoked with and pass them on to children. Changing inheritable process state behind the application's back is just unbelievably bad behavior and does not belong in a language runtime for a serious language... > > As an example, if you implement `find` in Rust, the `-exec` option will invoke its commands with `SIGPIPE` set to `SIG_IGN`, so that they will not properly terminate on broken pipe. But if you just made it set `SIGPIPE` to `SIG_DFL` before invoking the commands, now it would be broken in the case where the invoking user intentionally set `SIGPIPE` to `SIG_IGN` so that the commands would not die on broken pipe. There was discussion in 2019 about fixing this over an edition, but nothing came of it. Are we interested in fixing it over this one? Strawman (horrible) proposal: We could stop making this pre-main syscall in Rust 2024 and have `cargo fix` insert this syscall at the start of every `main` function. (In partial defense of the strawman, it gets us directly to the arguably best end result while having an automatic semantics-preserving edition migration and it avoids the concerns about lang/libs coupling that Mara raised. The edition migration could add a comment above this inserted code telling people under what circumstances they should either keep or delete the added line.) ### "types team / lang team interaction" rust#116557 **Link:** https://github.com/rust-lang/rust/issues/116557 TC: nikomatsakis nominated this: > We had some discussion about types/lang team interaction. We concluded a few things: > > * Pinging the team like @rust-lang/lang is not an effective way to get attention. Nomination is the only official way to get attention. > * It's ok to nominate things in an "advisory" capacity but not block (e.g., landing a PR), particularly as most any action can ultimately be reversed. But right now, triagebot doesn't track closed issues, so that's a bit risky. > > Action items: > > * We should fix triagebot to track closed issues. TC: What do we think? ### "UnsafePinned: allow aliasing of pinned mutable references" rfcs#3467 **Link:** https://github.com/rust-lang/rfcs/pull/3467 TC: We have a design meeting scheduled for this for 2024-05-29: https://github.com/rust-lang/lang-team/issues/266 ### "Implement `PartialOrd` and `Ord` for `Discriminant`" rust#106418 **Link:** https://github.com/rust-lang/rust/pull/106418 TC: We discussed this last in the meeting on 2024-03-13. scottmcm has now raised on concern on the issue and is planning to make a counter-proposal: > I remain concerned about exposing this with no opt-out on an unrestricted generic type @rfcbot concern overly-broad > > I'm committing to making an alternative proposal because I shouldn't block without one. Please hold my feet to the fire if that's no up in a week. > > Basically, I have an idea for how we might be able to do this, from [#106418 (comment)](https://github.com/rust-lang/rust/pull/106418#issuecomment-1698887324) > > > 2. Expose the variant ordering privately, only accessible by the type owner/module. > > > > Solution 2. is obviously more desirable, but AFAIK Rust can't do that and there is no proposal to add a feature like that. https://github.com/rust-lang/rust/pull/106418#issuecomment-1994833151 ### "Fallout from expansion of redundant import checking" rust#121708 **Link:** https://github.com/rust-lang/rust/issues/121708 TC: We discussed this in the meeting on 2024-03-13. The feelings expressed included: - We don't want to create a perverse incentive for people to expand existing lints rather than to create new ones where appropriate just because there's less process for expanding the meaning of an existing lint. - It would be good if potentially-disruptive expansions of an existing lint either: - Had a machine-applicable fix. - Or had a new name. - We don't want to require a new lint name for each expansion. - We don't want to require a crater run for each change to a lint. - There are two ways to prevent disruption worth exploring: - Prevent potentially-disruptive changes from hitting master. - Respond quickly to early indications of disruption once the changes hit master. - Compiler maintainers have a sense of what might be disruptive and are cautious to avoid it. It may be OK to have a policy that is not perfectly measurable. TC: tmandry volunteered to draft a policy proposal. ## Action item review - [Action items list](https://hackmd.io/gstfhtXYTHa3Jv-P_2RK7A) ## Pending lang team project proposals None. ## PRs on the lang-team repo ### "Add soqb`s design doc to variadics notes" lang-team#236 **Link:** https://github.com/rust-lang/lang-team/pull/236 ### "Update auto traits design notes with recent discussion" lang-team#237 **Link:** https://github.com/rust-lang/lang-team/pull/237 ### "Update hackmd link to a public link" lang-team#258 **Link:** https://github.com/rust-lang/lang-team/pull/258 ### "Adding a link to "how to add a feature gate" in the experimenting how-to" lang-team#267 **Link:** https://github.com/rust-lang/lang-team/pull/267 ## RFCs waiting to be merged ### "Precise capturing" rfcs#3617 **Link:** https://github.com/rust-lang/rfcs/pull/3617 ## `S-waiting-on-team` ### "Turn remaining non-structural-const-in-pattern lints into hard errors" rust#124661 **Link:** https://github.com/rust-lang/rust/pull/124661 ### "Warn (or error) when `Self` ctor from outer item is referenced in inner nested item" rust#124187 **Link:** https://github.com/rust-lang/rust/pull/124187 ### "Support C23's Variadics Without a Named Parameter" rust#124048 **Link:** https://github.com/rust-lang/rust/pull/124048 ### "Don't make statement nonterminals match pattern nonterminals" rust#120221 **Link:** https://github.com/rust-lang/rust/pull/120221 ### "Stabilize `count`, `ignore`, `index`, and `length` in Rust 1.80" rust#122808 **Link:** https://github.com/rust-lang/rust/pull/122808 ### "Better errors with bad/missing identifiers in MBEs" rust#118939 **Link:** https://github.com/rust-lang/rust/pull/118939 ### "warn less about non-exhaustive in ffi" rust#116863 **Link:** https://github.com/rust-lang/rust/pull/116863 ### "Rename `AsyncIterator` back to `Stream`, introduce an AFIT-based `AsyncIterator` trait" rust#119550 **Link:** https://github.com/rust-lang/rust/pull/119550 ### "Allow `#[deny]` inside `#[forbid]` as a no-op with a warning" rust#121560 **Link:** https://github.com/rust-lang/rust/pull/121560 ### "Fixup Windows verbatim paths when used with the `include!` macro" rust#125205 **Link:** https://github.com/rust-lang/rust/pull/125205 ## Proposed FCPs **Check your boxes!** ### "Match ergonomics 2024" rfcs#3627 **Link:** https://github.com/rust-lang/rfcs/pull/3627 ### "Use a default lifetime of `'static` in associated consts" rust#125190 **Link:** https://github.com/rust-lang/rust/issues/125190 ### "Bump `elided_lifetimes_in_associated_constant` to deny" rust#124211 **Link:** https://github.com/rust-lang/rust/pull/124211 ### "Tracking issue for function attribute `#[coverage]`" rust#84605 **Link:** https://github.com/rust-lang/rust/issues/84605 ### "Don't make statement nonterminals match pattern nonterminals" rust#120221 **Link:** https://github.com/rust-lang/rust/pull/120221 ### "`#![crate_name = EXPR]` semantically allows `EXPR` to be a macro call but otherwise mostly ignores it" rust#122001 **Link:** https://github.com/rust-lang/rust/issues/122001 ### "Stabilize `count`, `ignore`, `index`, and `length` in Rust 1.80" rust#122808 **Link:** https://github.com/rust-lang/rust/pull/122808 ### "Stabilize `anonymous_lifetime_in_impl_trait`" rust#107378 **Link:** https://github.com/rust-lang/rust/pull/107378 ### "add float semantics RFC" rfcs#3514 **Link:** https://github.com/rust-lang/rfcs/pull/3514 ### "[RFC] externally implementable functions" rfcs#3632 **Link:** https://github.com/rust-lang/rfcs/pull/3632 ### "Implement `PartialOrd` and `Ord` for `Discriminant`" rust#106418 **Link:** https://github.com/rust-lang/rust/pull/106418 ### "RFC: inherent trait implementation" rfcs#2375 **Link:** https://github.com/rust-lang/rfcs/pull/2375 ### "Don't allow unwinding from Drop impls" rfcs#3288 **Link:** https://github.com/rust-lang/rfcs/pull/3288 ### "Add text for the CFG OS Version RFC" rfcs#3379 **Link:** https://github.com/rust-lang/rfcs/pull/3379 ### "Add support for `use Trait::func`" rfcs#3591 **Link:** https://github.com/rust-lang/rfcs/pull/3591 ### "Tracking Issue for `const_cstr_from_ptr`" rust#113219 **Link:** https://github.com/rust-lang/rust/issues/113219 ### "Stabilize Wasm relaxed SIMD" rust#117468 **Link:** https://github.com/rust-lang/rust/pull/117468 ### "Stabilize associated type position impl Trait (ATPIT)" rust#120700 **Link:** https://github.com/rust-lang/rust/pull/120700 ### "Allow `#[deny]` inside `#[forbid]` as a no-op with a warning" rust#121560 **Link:** https://github.com/rust-lang/rust/pull/121560 ### "regression: let-else syntax restriction (right curly brace not allowed)" rust#121608 **Link:** https://github.com/rust-lang/rust/issues/121608 ## Active FCPs ### "Edition 2024: don't special-case diverging blocks" rust#123590 **Link:** https://github.com/rust-lang/rust/pull/123590 ### "Turn remaining non-structural-const-in-pattern lints into hard errors" rust#124661 **Link:** https://github.com/rust-lang/rust/pull/124661 ### "Support C23's Variadics Without a Named Parameter" rust#124048 **Link:** https://github.com/rust-lang/rust/pull/124048 ### "Tracking Issue for asm_const" rust#93332 **Link:** https://github.com/rust-lang/rust/issues/93332 ### "document guarantee about evaluation of associated consts and const blocks" reference#1497 **Link:** https://github.com/rust-lang/reference/pull/1497 ## P-critical issues None.