--- title: "Triage meeting 2024-02-07" tags: ["T-lang", "triage-meeting", "minutes"] date: 2024-02-07 discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202024-02-07 url: https://hackmd.io/M87Ytv1dToKMBmy6V4Bgjw --- # T-lang meeting agenda - Meeting date: 2024-02-07 ## Attendance - People: TC, Josh, Mara, eholk, tmandry, Santiago, Niko, Nadri, pnkfelix, CE ## Meeting roles - Minutes, driver: TC ## Scheduled meetings - 2024-02-07 - Planning meeting. 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!) ## Rust 2024 review Project board: https://github.com/orgs/rust-lang/projects/43/views/5 ### Tracking Issue for Lifetime Capture Rules 2024 (RFC 3498) #117587 **Link:** https://github.com/rust-lang/rust/issues/117587 TC: We accepted the RFC but it has a dependency on some means of expressing precise capturing. That probably means stabilizing TAIT. We're starting with stabilizing ATPIT, and we've now posted the stabilization report and PR for that. ### Reserve gen keyword in 2024 edition for Iterator generators #3513 **Link:** https://github.com/rust-lang/rfcs/pull/3513 TC: Oli is back, and we're all working on this. The minimum we need to do for 2024 is to reserve the keyword. ### Tracking issue for promoting `!` to a type (RFC 1216) #35121 **Link:** https://github.com/rust-lang/rust/issues/35121 TC: We're hoping to land a lint here and work is progressing on that. TC: This is what we want to lint against: ```rust fn never_type_fallback() { unsafe { if false { panic!() } else { transmute::<_, _ /* ?0 */>(()) } // later in fallback: ?0 := () // after ! stabilization: ?0 := ! }} ``` TC: Waffle has said that there are some complications about which he'll write. ## Nominated RFCs, PRs, and issues ### "Make unsafe_op_in_unsafe_fn warn-by-default starting in 2024 edition" rust#120535 **Link:** https://github.com/rust-lang/rust/issues/120535 TC: We talked about this last week and decided to propose FCP merge for doing a warn-by-default lint in Rust 2024 with an eye toward making this a lint across all editions. TC: However, Urgau then pointed out that, actually, we already agreed to do this via FCP on 2022-07-19: > Based on the various feedback we've received, I'm going to propose that we _should_ enable this by default in the 2024 edition, assuming that we have a rustfix that adds unsafe blocks as appropriate (ideally fine-grained unsafe blocks). > > @rust-lang/lang, shall we require `unsafe {}` for unsafe blocks even inside an `unsafe fn`, starting in the 2024 edition? > > Given that we are apparently _still_ warning in the other direction (which needs fixing ASAP), I'm going to reluctantly propose that we only move to warn-by-default in 2024, not deny-by-default. https://github.com/rust-lang/rust/issues/71668#issuecomment-1189396860 That FCP was then used to land this in Rust 2024: https://github.com/rust-lang/rust/pull/112038 TC: It's probably a moot point is we all go ahead and just check boxes here. After that, this seems done in terms of Rust 2024. JT: Let's FCP cancel and link to the earlier FCP. tmandry: Actually, I'll just check boxes based on the earlier FCP, then people can object there. JT: That's fine, no objection. *Consensus*: Let's let this go into FCP and note the earlier agreement. Looks like we're done here. ### "Stabilize associated type position impl Trait (ATPIT)" rust#120700 **Link:** https://github.com/rust-lang/rust/pull/120700 TC: We're proposing to stabilize a much-simplified version of associated type position impl Trait. The simplifications make this actually a small and natural extension to RPIT while solving a ton of important use cases. The main one that we're focusing attention on is "`async` blocks everywhere". E.g., without ATPIT, we must hand-implement `Future::poll` for some wrapper type to implement `IntoFuture`. With ATPIT, we can implement `IntoFuture` using `async` blocks. E.g.: ```rust use core::future::{Future, IntoFuture}; struct AlwaysAsync42; impl IntoFuture for AlwaysAsync42 { type Output = impl Iterator<Item = impl Fn() -> u8>; type IntoFuture = impl Future<Output = Self::Output>; fn into_future(self) -> Self::IntoFuture { async { core::iter::repeat(|| 42) }} } ``` The design is centered around three key design principles: - Convenience and minimal overhead for the common cases - Local reasoning - Crisp behavior TC: Since ATPIT is part of the story for precise capturing that allows landing the Lifetime Capture Rules 2024 in the new edition, this stabilization is edition-relevant. TC: What do we think? (We can hold the line and discuss after the triage call any general questions.) NM: I'm inclined to start the FCP merge. JT: +1 on the principle of starting FCP. We don't have to ask to ask. *Consensus*: Let's propose FCP merge. ### "RFC: New range types for Edition 2024" rfcs#3550 **Link:** https://github.com/rust-lang/rfcs/pull/3550 TC: We discussed this on 2024-01-24 and decided that we were OK, as far as the lang questions go, and proposed FCP merge jointly with T-libs-api. However, two things here deserve our attention. One is that we did not discuss what @pitaj proposed here: > The best solution I've seen along these lines is to make range syntax similar to integer literals, where the concrete range type is inferred based on context. This would cover the most prominent ergonomic drawbacks. > > The lang team should at least consider this. If T-lang decides that something along these lines is warranted, I am fully willing to modify the RFC to include it. He wanted, essentially, a gut check on that question. JT: If we can pull it off, that seems great. As always with inference, the trouble is the potential of making things ambiguous which weren't before. Range bounds come to mind here. NM: We should ask the types team about this. This does worry me. `for x in a..b` would itself be ambiguous and we'd need a rule to disambiguate. This gets back to type inference defaults, which we'd love to make process on. If there's a way we could tackle a subset, that would be great. Josh: For completeness: another route people have suggested is to have range syntax always produce the new types in the new edition, but allow coercion to the old types. Not sure we *want* to do that, but mentioning it as another solution that people have suggested. Mara: On this subject, I suggest taking a look at the point I make below. NM: It occurs to me there's another route here. Type inference is a hybrid system. We take into account the context. There's a rule here we could adopt here that would sidestep the fallback problems. E.g.: ```rust let i = 0..5; // no expected type, uses 'new' range let i: LegacyRange = 0..5; // expected type is legacy range, uses 'old' range takes_range_1(0..5); // expected type comes from fn below, uses "legacy" range takes_range_2(0..5); // no expected type, chooes "new" range // importantly fn takes_range_1(range: std::range::legacy::Range<usize>) {} fn takes_range_2<R>(range: std::range::legacy::Range<usize>) where R: Something, {} ``` ---- TC: That may have some relevance to the second issue we should discuss, which is that Mara has raised concerns about the migration: https://github.com/rust-lang/rfcs/pull/3550#issuecomment-1919054372 > I'm afraid that automatic edition migration will not result in an acceptable outcome. > > The RFC gives this example for what the automatic edition migration will do: > ```rust // Before pub fn takes_range(range: std::ops::Range<usize>) { ... } takes_range(0..5); // After pub fn takes_range(range: std::range::legacy::Range<usize>) { ... } takes_range((0..5).to_legacy()); ``` > > I'm not fully convinced this acceptible. > > The same code newly written in the new edition would look different: > ```rust pub fn takes_range(range: std::range::Range<usize>) { ... } takes_range(0..5); ``` > > But automatic edition migration cannot give that result, simply because it isn't backwards compatible, and because the function definition and function call might be in different crates. We should see whether there's anything that we can do about that on the lang side nikomatsakis: The traditional approach has been to have a second lint, in Rust 2024, that rewrites code that uses legacy ranges. We call those "idiom" lints. NM: We have in the past separated migration lints and idiom lints. The latter lints are not required to be semantics-preserving. Mara: My concern is the pressure on crate maintainers to do explicit things to support both editions. NM: Understand, but disagree. We decided that editions are meant to be adopted. So I don't have a lot of sympathy there. We could say the same about new keywords, where, e.g. using the keyword in some editions is going to be more awkward. It's a valid concern, but it would be too strict a limitation on editions in general. Mara: I have crates in my dependency tree that haven't been updated to the new edition. It would seem I'd need to use extra syntax to interact with these. tmandry: Is it a backward compatible change to update a crate to the new thing? JT: It can work if all of your callers are compatible with it, but it can break inference. NM: Are you refering to moving between concrete types, or moving from concrete to opaque? JT: I'm talking about concrete to concrete. NM: This example, I think mitigates this: ```rust let i = 0..5; // no expected type, uses 'new' range let i: LegacyRange = 0..5; // expected type is legacy range, uses 'old' range takes_range_1(0..5); // expected type comes from fn below, uses "legacy" range takes_range_2(0..5); // no expected type, chooes "new" range // importantly fn takes_range_1(range: std::range::legacy::Range<usize>) {} fn takes_range_2<R>(range: std::range::legacy::Range<usize>) where R: Something, {} ``` Mara: What about the `Index` trait? I don't think you could turn those into a generic. NM: You'd have to add a new impl. Unlike before, you can have both impls. Mara: But new crates that will only be implemented for the new thing. How much pressure are we putting on crate maintainers? NM: This decisions leans heavily on the principle that editions are meant to be adopted. JT: It seems unlikely people would be able to use bounds for the `Index` case. JT: Have we confirmed here whether we're going to use entirely new `Range` types versus reusing the legacy one where possible? TC: The RFC said to use new ones, but we may have delegated that to T-libs-api. NM: My hunch is that most people using range types are using the exclusive version more than the inclusive version. Given that these can be compatible, that may mitigate the impact. Mara: It's OK if it doesn't solve all of those problems. But I'm not seeing an analysis of the impact. NM: Let's start with quantifying the impact. What specific data would we like to gather? I'd like to see: - How often is each range type used concretely by name in crates and in which positions (i.e., in fn arguments, struct fields, Index impls, other impls)? - In particular, this may be relevant how often `Range` vs `RangeInclusive` is used concretely; we expect the latter may be more rare. - How often are the range traits used and in which positions? - How often do people use `..` vs `..=` syntax? NM: We should focus on the first point above. JT: Agree with that. Is there any way we could use crater to get this data? NM: If we made the change, we could certainly do a crater run. JT: We could do a hack to pretend we're making the change in Rust 2021. Would need some care to test what we want to test, but might work. Mara: Other than just number of crates, it'd be good to set out what we expect library maintainers to do. NM: So let's write out the guidance that we'll provide to library maintainers. E.g. what to do about the `Index` case. JT: I have seen the use of concrete range types in ADTs. I've never seen the inclusive range type used concretely other than in `Index`/`IndexMut`. But we should collect data to support this hypothesis. NM: There is an asterisk on the idea that editions are crate local; crates may need to change to better support users on newer editions. JT: It could require work from crate maintainers, and that's an OK thing to do. JT: Part of the issue here is MSRV. If we want an existing crate maintainer to support the new types (e.g. in `Index`/`IndexMut`), that would require a new Rust version. NM: Probably. I'm skeptical about MSRV and we need a more systematic solution. We can't constrain our language evolution by the fact that people may want to compile with any old version of the compiler. What we're really asking users to do is to keep up with language idioms; the fact that it's tied to an edition is not (in my opinion) the high order bit. JT: If we provide `cfg_accessible` or `cfg(version(...))` or even some `cfg` specific to the new index types, then it would be easier for people to conditionalize this. That would solve the problem of being torn between MSRV and supporting users on newer editions. Mara: Maybe an `impl Index<OldRange>` should imply `impl Index<NewRange>` and the other way around. Might be a terrible idea, but there needs to be a tradeoff with the work we expect from library maintainers. *Consensus*: Let's ask for an articulation of what we would recommend library maintainers do, let's ask for data collection, and let's ask if there is some solution that would allow library maintainers to do no work to support users on newer editions. (We may not want to use that solution, but we should explicitly consider the tradeoff.) (The meeting ended here.) ### "Tracking Issue for `min_exhaustive_patterns`" rust#119612 **Link:** https://github.com/rust-lang/rust/issues/119612 TC: Nadri has a proposal for us to move forward with exhaustive patterns: > [The min_exhaustive_patterns] feature allows users to omit match arms on empty types _when the empty type is matched by-value_. This is a guaranteed-sound subset of the [`exhaustive_patterns`](https://github.com/rust-lang/rust/issues/51085) feature. This allows: ```rust enum Void {} let x: Result<T, Void> = foo(); match x { // ok Ok(y) => ..., } let Ok(y) = x; // ok ``` > If `x: &Result<T, Void>` or `x: Result<T, &Void>` or we're matching behind a pointer/union then this changes nothing (i.e. we require a `Err(_)` arm like on stable rust). In contrast, `exhaustive_patterns` allows omitting match arms on empty types in all cases, which can cause UB. For more detail see the OP. > > Because it's a well-behaved and useful subset, I'd like to move to stabilize it soon. We can think about the rest of `exhaustive_patterns` later. [Never patterns](https://github.com/rust-lang/rust/issues/118155) are a likely part of the final plan, and they need more time (and would benefit from this being stabilized). > > ## Proposal > > If T-lang approves, I will: > > * mark the feature gate as non-incomplete (that's the part I feel I need approval for); > * use `min_exhaustive_patterns` instead of `exhaustive_patterns` in rustc, std and tests wherever possible; > * call for the testing of this feature; > * make a stabilization PR, and ask for T-lang approval again. > For the triage meeting I prepared step 1 and 2 here: https://github.com/rust-lang/rust/pull/120742 > > It appears that the vast majority of in-tree use cases of `exhaustive_patterns` are covered by `min_exhaustive_patterns`, as hoped. TC: What do we think? ### "RFC: Rust Has Provenance" rfcs#3559 **Link:** https://github.com/rust-lang/rfcs/pull/3559 TC: The key observation in the RFC is that Rust *already has provenance* assuming we agree that this program has undefined behavior: ```rust fn main() { unsafe { let mut x = 5; // Setup a mutable raw pointer and a shared reference to `x`, // and derive a raw pointer from that shared reference. let ptr = &mut x as *mut i32; let shrref = &*ptr; let shrptr = shrref as *const i32 as *mut i32; // `ptr` and `shrptr` point to the same address. assert_eq!(ptr, shrptr); // And yet, while writing to `ptr` here is perfectly fine, // the next line is UB! shrptr.write(0); // alternative: `ptr.write(0);` } } ``` This RFC does not propose any new APIs, syntax, etc. Its purpose is just to settle the question of whether Rust has provenance. TC: What do we think? ### "Tracking Issue for cfg-target-abi" rust#80970 **Link:** https://github.com/rust-lang/rust/issues/80970 TC: Chris Denton proposes to stabilize `#[cfg(target_abi = "..")]`: > ## Stabilization report > > I propose to stabilize `#[cfg(target_abi = "...")]`, This implements [RFC-2992](https://rust-lang.github.io/rfcs/2992-cfg-target-abi.html) (cfg-target-abi). The implementation was completed in #86922 and this tracking issue was subsequently marked as ready for stabilization by @joshtriplett. > > ### Summary > > This stabilizes the `cfg` option called `target_abi`: > > ```rust > #[cfg(target_abi = "macabi")] > ``` > > And `target_abi` is also shown when using `--print=cfg` (output snipped for length): > > ``` > > rustc --print=cfg --target aarch64-apple-ios-sim > > target_abi="sim" > target_arch="aarch64" > target_env="" > target_os="ios" > target_vendor="apple" > ``` > > Without `target_abi`, cfgs are limited to `target_arch`, `target_vendor`, `target_os`, and `target_env`. However, some targets are only differentiated by their abi and thus it's necessary to resort to parsing the full target string in a build script when there's a need to disambiguate. For example, the following targets are the same if only using stable `target_*` `cfg`s: > > * `aarch64-apple-ios` and `aarch64-apple-ios-sim` (arch: "aarch64", vendor: "apple", os: "ios", env: "") > * `x86_64-pc-windows-gnullvm` and `x86_64-pc-windows-gnu` (arch: "`x86_64", vendor: "pc", os: "windows", env: "gnu") > > ### Notes > > The `target_abi` defaults to `""` (the empty string) and most targets don't set it. This is similar to `target_env` where if it's not needed for disambiguation then it's often not set. > > In the future `target_abi` could be an array of zero or more properties that affect the ABI (e.g. `softfloat` may be combined with other ABI properties), However, this feature can be added later without breaking compatibility. TC: Given the recent discussions over ABI issues, I made sure RalfJ was aware of this, and he had no particular concerns. TC: What do we think? ### "Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute" rust#119888 **Link:** https://github.com/rust-lang/rust/pull/119888 TC: weiznich proposes `#[diagnostic::on_unimplemented]` for stabilization: > This PR stabilizes the `#[diagnostic]` attribute namespace and a minimal option of the `#[diagnostic::on_unimplemented]` attribute. > > The `#[diagnostic]` attribute namespace is meant to provide a home for attributes that allow users to influence error messages emitted by the compiler. The compiler is not guaranteed to use any of this hints, however it should accept any (non-)existing attribute in this namespace and potentially emit lint-warnings for unused attributes and options. This is meant to allow discarding certain attributes/options in the future to allow fundamental changes to the compiler without the need to keep then non-meaningful options working. > > The `#[diagnostic::on_unimplemented]` attribute is allowed to appear on a trait definition. This allows crate authors to hint the compiler to emit a specific error message if a certain trait is not implemented. For the `#[diagnostic::on_unimplemented]` attribute the following options are implemented: > > * `message` which provides the text for the top level error message > * `label` which provides the text for the label shown inline in the broken code in the error message > * `note` which provides additional notes. > > The `note` option can appear several times, which results in several note messages being emitted. If any of the other options appears several times the first occurrence of the relevant option specifies the actually used value. Any other occurrence generates an lint warning. For any other non-existing option a lint-warning is generated. > > All three options accept a text as argument. This text is allowed to contain format parameters referring to generic argument or `Self` by name via the `{Self}` or `{NameOfGenericArgument}` syntax. For any non-existing argument a lint warning is generated. > > This allows to have a trait definition like: > ```rust #[diagnostic::on_unimplemented( message = "My Message for `ImportantTrait<{A}>` implemented for `{Self}`", label = "My Label", note = "Note 1", note = "Note 2" )] trait ImportantTrait<A> {} ``` > > which then generates for the following code > ```rust fn use_my_trait(_: impl ImportantTrait<i32>) {} fn main() { use_my_trait(String::new()); } ``` > > this error message: > ``` error[E0277]: My Message for `ImportantTrait<i32>` implemented for `String` --> src/main.rs:14:18 | 14 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait<i32>` is not implemented for `String` = note: Note 1 = note: Note 2 ``` > > [Playground with the unstable feature](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7ffa5c88627251ab242fadadd3b6f65f) TC: What do we think? ### "privacy: Stabilize lint `unnameable_types`" rust#120144 **Link:** https://github.com/rust-lang/rust/pull/120144 TC: petrochenkov nominates this for us and describes the change: > This is the last piece of ["RFC #2145: Type privacy and private-in-public lints"](https://github.com/rust-lang/rust/issues/48054). > > Having unstable lints is not very useful because you cannot even dogfood them in the compiler/stdlib in this case (#113284). The worst thing that may happen when a lint is removed are some `removed_lints` warnings, but I haven't heard anyone suggesting removing this specific lint. > > This lint is allow-by-default and is supposed to be enabled explicitly. Some false positives are expected, because sometimes unnameable types are a legitimate pattern. This lint also have some unnecessary false positives, that can be fixed - see #120146 and #120149. TC: What do we think? ### "`c_unwind` full stabilization request: change in `extern "C"` behavior" rust#115285 **Link:** https://github.com/rust-lang/rust/issues/115285 TC: BatmanAoD proposes for stabilization: > This is a request for _full_ stabilization of the `c_unwind` feature, [RFC-2945](https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md). The behavior of non-`"Rust"`, non-`unwind` ABIs (such as `extern "C"`) will be modified to close soundness holes caused by permitting stack-unwinding to cross FFI boundaries that do not support unwinding. > > ## Summary > > When using `panic=unwind`, if a Rust function marked `extern "C"` panics (and that panic is not caught), the runtime will now abort. > > Previously, the runtime would simply attempt to unwind the caller's stack, but the behavior when doing so was undefined, because `extern "C"` functions are optimized with the assumption that they cannot unwind (i.e. in `rustc`, they are given the LLVM `nounwind` annotation). > > This affects existing programs. If a program relies on a Rust panic "escaping" from `extern "C"`: > > * It is currently unsound. > * Once this feature is stabilized, the program will crash when this occurs, whereas previously it may have appeared to work as expected. > * Replacing `extern "x"` with `extern "x-unwind"` will produce the intended behavior without the unsoundness. > > The behavior of function calls using `extern "C"` is unchanged; thus, it is still undefined behavior to call a C++ function that throws an exception using the `extern "C"` ABI, even when compiling with `panic=unwind`. TC: We had been waiting for a crater run and analysis on this, and that has now been completed: https://github.com/rust-lang/rust/pull/116088#issuecomment-1870577466 There were no regressions of substance. From an implementation perspective, this does seem currently blocked on [#113923](https://github.com/rust-lang/rust/pull/113923), which was [reverted](https://github.com/rust-lang/rust/pull/119885), but that probably doesn't need to block our FCP on the language questions. TC: What do we think? ### "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. TC: What do we think? ### "Make `ConstPropLint` lint run on promoteds" rust#119432 **Link:** https://github.com/rust-lang/rust/pull/119432 TC: Oli nominates this for us: > Nominating for T-lang for awareness.... TLDR: existing lints will trigger in more situations where we were missing them before. In our test suite this causes duplicate lint emissions, but they are deduplicated for users. gurry: > Fixes #117949 wherein the lint didn't fire for the following promoteds: > > * SHL or SHR operators in a non-optimized build > * any arithmetic operator in an optimized build > > What I have done here is simply enabled `ConstPropLint` to run on promoted bodies by removing the relevant `if` check. > > After this change _all_ promoted arithmetic operators will lint _in both non-optimized and optimized builds_. On the flip side programs containing the above mentioned overflowing promoteds that were accepted earlier will now be rejected. Hope that is okay from a backward compatibility standpoint. > > I have added tests covering all overflowing promoted & non-promoted ops for both compile-time and runtime operations and for optimized as well as non-optimized builds. > > I had to amend some existing tests to make them pass and had to delete a couple that were set to pass despite overflows. > > This PR increases the number of duplicate diagnostics emitted (because the same operator might get linted in both the promoted MIR and the main MIR). I hope that is an acceptable trade-off given that we now lint overflows much more comprehensively than earlier. TC: What do we think? ### "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? ### "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? ### "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: > Right now, the heuristic we use to check if a token may begin a pattern nonterminal falls back to `may_be_ident`. > > This has the unfortunate side effect that a `stmt` nonterminal eagerly matches against a `pat` nonterminal, leading to a parse error: > ```rust macro_rules! m { ($pat:pat) => {}; ($stmt:stmt) => {}; } macro_rules! m2 { ($stmt:stmt) => { m! { $stmt } }; } m2! { let x = 1 } ``` > > This PR fixes it by more accurately reflecting the set of nonterminals that may begin a pattern nonterminal. > > As a side-effect, I modified `Token::can_begin_pattern` to work correctly and used that in `Parser::nonterminal_may_begin_with`. TC: What do we think? ### "Lint singleton gaps after exclusive ranges" rust#118879 **Link:** https://github.com/rust-lang/rust/pull/118879 TC: Nadri describes the change: > In the discussion to stabilize exclusive range patterns (#37854), it has often come up that they're likely to cause off-by-one mistakes. We already have the `overlapping_range_endpoints` lint, so I [proposed](https://github.com/rust-lang/rust/issues/37854#issuecomment-1845580712) a lint to catch the complementary mistake. > > This PR adds a new `non_contiguous_range_endpoints` lint that catches likely off-by-one errors with exclusive range patterns. Here's the idea (see the test file for more examples): > > ```rust > match x { > 0..10 => ..., // WARN: this range doesn't match `10_u8` because `..` is an exclusive range > 11..20 => ..., // this could appear to continue range `0_u8..10_u8`, but `10_u8` isn't matched by either of them > _ => ..., > } > // help: use an inclusive range instead: `0_u8..=10_u8` > ``` > > More precisely: for any exclusive range `lo..hi`, if `hi+1` is matched by another range but `hi` isn't, we suggest writing an inclusive range `lo..=hi` instead. We also catch `lo..T::MAX`. TC: What do we think? ### "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. TC: Where do we want to go from here? ### "Implement RFC 3373: Avoid non-local definitions in functions" rust#120393 **Link:** https://github.com/rust-lang/rust/pull/120393 TC: We agreed to accept RFC 3373 (regarding "sneaky inner impls") after changing it to make it a warn-by-default lint. That lint has now been implemented, and a crater run has been performed. This is the analysis: > Affected projects: 7057 / 851203 (0.82%) Total errors: 116165 > > Errors from derive macros: 107531 (across 259 different derive macros) Errors from `macro_rules!`: 2150 (across 117 different `macro_rules!`) Errors (manual, not above): 6484 > > In conclusion, this crater run revealed that making the lint deny-by-default (which is NOT the default that would would be used, it would be warn-by-default) would break 7057 crates / 851203 crates tested (0.82%), there was a total of 116165 errors, of which 107531 (92.6%) errors were coming from derives macros, 2150 were coming from `macro_rules!` and 6484 errors are not coming from either of them. > > Analysing the root of those derives and macros revealed many outdated versions of `serde_derive` and `diesel_derives`, representing nearly 74% of the total errors alone, as well 6 different derive crates that represent 11.4% that would need to be updated. > > To put it simply: > > * 84523 (76.3%) errors would be fixed by `cargo update` (representing 6104 different crates) > * 12660 (11.4%) errors that could fixed by upstream change (at least 5 different derive crates) > * 6484 (5.9%) errors requires manual intervention (788 different crates) > * 7309 (6.6%) uncategorised errors (probably manual intervention and deps change): 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? ### "unsafe attributes" rfcs#3325 **Link:** https://github.com/rust-lang/rfcs/pull/3325 TC: tmandry nominated this one for us so that we could finish the bikeshed that we started in time for Rust 2024. Lokathor laid out these options: > The three basic proposals are: > > * `#[unsafe attr]` ("unsafe space") > * `#[unsafe(attr)]` ("unsafe parens") > * `#[unsafe { attr }]` ("unsafe braces") > > During the lang meeting on 2023-06-06, it was requested that a summary of how each option actually _looks_ in practice be made,so that hopefully one of the proposals can be selected based on readability. > > When using an attribute, the attribute itself can be one of three basic forms: > > * lone token: `#[no_mangle]` > > * `#[unsafe no_mangle]` > * `#[unsafe(no_mangle)]` > * `#[unsafe { no_mangle }]` > > * key-val expression: `#[link_section = ".foo"]` > > * `#[unsafe link_section = ".foo"]` > * `#[unsafe(link_section = ".foo")]` > * `#[unsafe { link_section = ".foo" }]` > > * an attribute "call": `#[link_ordinal(15)]` > > * `#[unsafe link_ordinal(15)]` > * `#[unsafe(link_ordinal(15))]` > * `#[unsafe { link_ordinal(15) }]` > > There is also the issue of readability when mixed with `cfg_attr`. > > * Interior, around only the attribute: > > * `#[cfg_attr(cond, unsafe no_mangle)]` > * `#[cfg_attr(cond, unsafe(no_mangle)]` > * `#[cfg_attr(cond, unsafe { no_mangle } )]` > > * Exterior, around the `cfg_attr`: > > * `#[unsafe cfg_attr(cond, no_mangle)]` > * `#[unsafe(cfg_attr(cond, no_mangle))]` > * `#[unsafe { cfg_attr(cond, no_mangle ) }]` TC: This is an interesting case because we are not *discharging* unsafety, as with `unsafe { expr }` in a function body. Neither does saying `unsafe` here create and push upward a type-checked *obligation*. Instead, the upward obligation exists regardless and there is no means to signal to the compiler that it has been discharged and no enforcement of that. TC: Another option I've seen discussed is finding some way to make these annotations safe. 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? ### "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? ### "#[cold] on match arms" rust#120193 **Link:** https://github.com/rust-lang/rust/pull/120193 TC: Apparently our unstable `likely` and `unlikel` 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. ### "`.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. TC: There's now been a crater run done for this. The result was that this breaks a small number of crates, but at least one of those crates has a large number of dependents (`aws-smithy-runtime`). It can be fixed in the dependency in such a way that dependent crates do not have to make changes, but those dependent crates would need to update to a fixed version of the dependency. (See this [discussion](https://rust-lang.zulipchat.com/#narrow/stream/187312-wg-async/topic/Perform.20autoref.2Fautoderef.20on.20.2Eawait.20-.20.23111773).) TC: What do we think? ### "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 TC: Is this something we want to do? ### "Arbitrary self types v2" rfcs#3519 **Link:** https://github.com/rust-lang/rfcs/pull/3519 TC: We discussed this on 2023-11-22. The general feeling seemed to be that we wanted to find some way to enable this, including for raw pointers, `NonNull`, etc., but we were feeling unsure about the path to get there. We asked the author to cogitate on this and come back with a revised plan. TC: The author did that, and we had an extensive discussion on 2024-01-17 without consensus. We have open threads for discussing this asynchronously. Here's the thread for the proposal: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Arbitrary.20self.20types.20v2.20RFC And here's the thread for the broader question of whether we want arbitrary self types at all: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Do.20we.20want.20arbitrary.20self.20types.3F ### "RFC: Syntax for embedding cargo-script manifests" rfcs#3503 **Link:** https://github.com/rust-lang/rfcs/pull/3503 TC: We discussed this for most of one triage meeting in November without reaching any consensus. There is a design meeting proposal, but we have not yet scheduled it for a date. At Josh's suggestion, Ed Page has renominated this for us. Earlier context included: > @**scottmcm** raised these interesting points: > > > My biggest question here is how much it should be thought of as tied to the script use, and thus to the `#!`. > > > > My instinct is that either > > > > 1. This is tied to the shebang, so there's only one of them, to be consumed only by whatever tool is in the shebang, and rustc completely ignores it, like we completely ignore the shebang line. And thus the "`` ``` `` right after the shebang" syntax seems entirely reasonable to me. > > 2. This is a general tool feature, for which there will be multiple of them, and for which they'd want something like tool attribute namespacing so there's a clear route to lots of them under understood namespaces, and are a full part of the parsed structure of the crate, maybe included in rustdoc, etc. (Like perhaps `--document-private-items` on a crate would show an embedded `rustfmt::config` block somewhere, one day.) > > @**nikomatsakis** noted that, even if it's tied to a shebang, he doesn't see a reason to limit it to only one. > > @**tmandry** suggested that: > > > With my lang hat on, I don't see a reason we should RFC a feature that only allows `cargo` front matter, without specifying a path to generalizing it to other tooling. If we want to be conservative in what we stabilize, let's approach that in the stabilization rather than in the RFC. > > In the meeting, @**nikomatsakis** suggested that we seem misaligned on the purpose of this. Others in the meeting suggested that the syntax should derive from a clear understanding of that purpose and the eventual goals for it. TC: We've since discussed this asynchronously here: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Syntax.20for.20embedded.20tooling.20metadata/near/409126434 We seemed to agree that: - `.rs` files should parse as valid Rust. - I.e., we don't want to expect the runner to have to strip out these blocks. - Rust itself should not validate the content of these blocks. The open questions include: - Should there be only one of these blocks or potentially many? - If we only support one block, tools that need many will define their own syntax for delineation. - It could be awkward to change our mind later on this, as tools will have already defined this delineation in their own SemVer commitments. - Supporting only one is simpler (for us) and gives tools flexibility. - But if we want IDEs to eventually support syntax highlighting for these blocks (e.g. based on the file type indicated in the info string), then we probably need to handle this ourselves. - tmandry: "Making that kind of editor integration possible is important to me, even though I expect that many editors won't support that level of generality in their syntax definitions today." - Relatedly, do we want to support info strings? - Should the shebang be optional or required when using these blocks? - It's more conventional for the shebang to be optional. - If it's required, people may end up writing e.g. `#!/bin/false` as a workaround. - The shebang is meaningless for Windows. - What syntax to use? - Triple (or more) backticks. - Upside: Beginners may prefer this, but of course they would due to Markdown familiarity. - Downside: Even figuring out how to encode those backticks literally in this document is difficult. Users would need to know advanced Markdown to encode these Rust files. Some markdown parsers (e.g. the one for Discord) are not sophisticated enough to allow this. - tmandry: "I think that is a serious quality of life hazard we should be cognizant of. If I were to boil it down to a principle I would say that Rust should feel pleasant to use, and that includes in places like github comments, chatrooms, and forums, where many people write Rust code every day!" - Downside: It's a new matched string literal syntax when Rust already uses `#` for this. - Triple (or more) hashes (`###`). - Upside: This would look natural with the shebang and would suggest association with the shebang. - Upside: Rust already uses matched `#`s for literals. - Downside: We may want a space before the info string. - Triple (or more) dashes (`---`). - Upside/downside: This is associated with YAML header blocks. - Downside: It's a new matched string literal syntax when Rust already uses `#` for this. - Downside: This may look less natural with an info string, or we may want a space before it. There is an open experiment on the `cargo` side that simulates the various syntax options, e.g.: - https://github.com/rust-lang/cargo/pull/13241 - https://github.com/rust-lang/cargo/pull/13247 TC: What do we think? ### "Decision on "must define before use" for opaque types" rust#117866 **Link:** https://github.com/rust-lang/rust/issues/117866 TC: The question is whether to adopt the following "must define before use" rule for opaque types: > 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. This is a breaking change to RPIT. Here's an example of code that works today that would break under this rule: ```rust use core::convert::identity; struct I; struct IShow; impl I { fn show(&self) -> IShow { IShow } } struct OnIShow; trait OnI { fn show(&self) -> OnIShow { OnIShow } } impl OnI for I {} fn test(n: bool) -> impl OnI { let true = n else { loop {} }; let x = test(!n); //~ NOTE this is the opaque type let _: OnIShow = x.show(); //~ NOTE this is a non-defining use //~^ ERROR if the body registers a hidden type for the opaque, it // must do so *before* using it opaquely let _: IShow = identity::<I>(x).show(); //~^ NOTE this registers a hidden type for the opaque, but does so // too late loop {} } fn main() {} ``` This rule has relevance to the new trait solver. TC: What do we think? ### "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 ### "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. `!`, `*`, `&`)? ### "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? ## 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` ### "[ptr] Document maximum allocation size" rust#116675 **Link:** https://github.com/rust-lang/rust/pull/116675 ### "warn less about non-exhaustive in ffi" rust#116863 **Link:** https://github.com/rust-lang/rust/pull/116863 ### "Add lint against function pointer comparisons" rust#118833 **Link:** https://github.com/rust-lang/rust/pull/118833 ### "Lint singleton gaps after exclusive ranges" rust#118879 **Link:** https://github.com/rust-lang/rust/pull/118879 ### "Make `ConstPropLint` lint run on promoteds" rust#119432 **Link:** https://github.com/rust-lang/rust/pull/119432 ### "Rename `AsyncIterator` back to `Stream`, introduce an AFIT-based `AsyncIterator` trait" rust#119550 **Link:** https://github.com/rust-lang/rust/pull/119550 ### "privacy: Stabilize lint `unnameable_types`" rust#120144 **Link:** https://github.com/rust-lang/rust/pull/120144 ## 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 text for the CFG OS Version RFC" rfcs#3379 **Link:** https://github.com/rust-lang/rfcs/pull/3379 ### "RFC: Syntax for embedding cargo-script manifests" rfcs#3503 **Link:** https://github.com/rust-lang/rfcs/pull/3503 ### "add float semantics RFC" rfcs#3514 **Link:** https://github.com/rust-lang/rfcs/pull/3514 ### "RFC: patchable-function-entry" rfcs#3543 **Link:** https://github.com/rust-lang/rfcs/pull/3543 ### "RFC: New range types for Edition 2024" rfcs#3550 **Link:** https://github.com/rust-lang/rfcs/pull/3550 ### "RFC: Rust Has Provenance" rfcs#3559 **Link:** https://github.com/rust-lang/rfcs/pull/3559 ### "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 ### "[ptr] Document maximum allocation size" rust#116675 **Link:** https://github.com/rust-lang/rust/pull/116675 ### "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 ### "Add `REDUNDANT_LIFETIMES` lint to detect lifetimes which are semantically redundant" rust#118391 **Link:** https://github.com/rust-lang/rust/pull/118391 ### "Make unsafe_op_in_unsafe_fn warn-by-default starting in 2024 edition" rust#120535 **Link:** https://github.com/rust-lang/rust/issues/120535 ## Active FCPs ### "static mut: allow mutable reference to arbitrary types, not just slices and arrays" rust#117614 **Link:** https://github.com/rust-lang/rust/pull/117614 ## P-critical issues None.