-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stabilize let_chains
in Rust 1.64
#94927
Conversation
Some changes occurred in src/tools/clippy. cc @rust-lang/clippy |
r? @estebank (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
I wonder about linting for irrefutable assignments. This code gives you a if let v = 4 + 4 { /*...*/ }
//^ WARNING: irrefutable `if let` pattern On a similar note, I expect this code to lint: if let v = 4 + 4 && let w = 8 + 8 { ... } But there is no warning at all. It's a bit confusing to have an Generally, it makes sense to not lint for irrefutable patterns inside However, I think both trailing and leading irrefutable patterns should be linted, as well as the combination of both cases, let chains made up of only irrefutable assignments. Leading assignments can be made part of the body the I'm not sure if this lint needs to be in rust, or it is better present in clippy though. As the |
478f49d
to
6d4cd8a
Compare
@est31 I agree. Technically we can always introduce that lint later, but I think we should have it in place before we ship let chains in stable, since it will affect how people start writing let chains. |
@joshtriplett, should a PR like this one should be approved by consensus of t-lang, or should t-compiler take on that responsibility once we receive a go ahead? Either way, I don't currently have the bandwidth to shepherd this myself and would hate to be the cause of it stalling. |
@estebank Historically, I think the way we've handled that is to have two separate aspects of approval: the feature stabilization, and the PR content.
In this particular case, while the PR is large, it looks like a straightforward stabilization of the feature gate, plus the extensive updating of usages of the feature gate. Seems like any compiler reviewer could reasonably r+ this, once the stabilization is approved? |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
FWIW Clippy has an internal lint for exactly this inside the rust/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs Lines 1184 to 1198 in 95561b3
This lint could be used as a basis for implementing the same for |
I've filed a PR to extend the irrefutable patterns lint to the prefixes/suffixes of let chains: #94951 @flip1995 thanks for the suggestion about the clippy lint. Maybe that lint is even the cause for my suggestion above, as it's possible I got warned by it back when I wrote my clippy PR, I'm not sure any more. I've checked out the implementation to see if I can do something differently in #94951. Mostly I note that it's more compact, probably due to the rich set of utilities that clippy has. Also, maybe the error messages can be improved a little. |
Yeah the clippy utils really help with writing lints. It might also just be that internal Clippy lints usually don't really care about producing good suggestions/messages, because they're not user facing and we have a lower bar there. |
@rfcbot fcp reviewed +1 in general |
@rfcbot concern doc-pr Do we have a pending update to the Rust reference? |
Big thank you to @c410-f3r and others involved in pushing this feature forward! |
@rfcbot concern let_else-interaction Do we have existing tests verifying that this feature interacts nicely with |
@estebank When that has come up previously, our general conclusion of the interaction between let chains and let else was "don't": they don't mix at all. Adding a failing test to ensure that the compiler does not allow attaching an |
b46a579
to
3266460
Compare
Rebased due to recent code conflict. |
@bors r+ |
Rollup of 7 pull requests Successful merges: - rust-lang#94927 (Stabilize `let_chains` in Rust 1.64) - rust-lang#97915 (Implement `fmt::Write` for `OsString`) - rust-lang#99036 (Add `#[test]` to functions in test modules) - rust-lang#99088 (Document and stabilize process_set_process_group) - rust-lang#99302 (add tracking issue to generic member access APIs) - rust-lang#99306 (Stabilize `future_poll_fn`) - rust-lang#99354 (Add regression test for rust-lang#95829) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Just for reference, this was reverted in #100538, thus will likely not be in 1.64 release. |
Because of this ^^ @rustbot label -relnotes |
…compiler-errors Additional tests to ensure let is rejected during parsing In the original stabilization PR, @ `compiler-errors` has [pointed out](rust-lang#94927 (comment)) that rust-lang#97295 wasn't enough to address the concerns about having `let` in expressions being rejected at parsing time, instead of later. Thankfully, since then the situation has been greatly improved by rust-lang#115677. This PR adds some additional tests to `disallowed-positions.rs`, and adds two additional revisions to the "normal" case which is now given the `feature` name: * `no_feature`: Added to incorporate `disallowed-positions-without-feature-gate.rs` into the file, reducing duplication. * `nothing`: like feature, but all functions are cfg'd out. Ensures that the errors are really emitted during parsing. cc tracking issue rust-lang#53667
Rollup merge of rust-lang#132828 - est31:let_chains_parsing_tests, r=compiler-errors Additional tests to ensure let is rejected during parsing In the original stabilization PR, @ `compiler-errors` has [pointed out](rust-lang#94927 (comment)) that rust-lang#97295 wasn't enough to address the concerns about having `let` in expressions being rejected at parsing time, instead of later. Thankfully, since then the situation has been greatly improved by rust-lang#115677. This PR adds some additional tests to `disallowed-positions.rs`, and adds two additional revisions to the "normal" case which is now given the `feature` name: * `no_feature`: Added to incorporate `disallowed-positions-without-feature-gate.rs` into the file, reducing duplication. * `nothing`: like feature, but all functions are cfg'd out. Ensures that the errors are really emitted during parsing. cc tracking issue rust-lang#53667
…errors Additional tests to ensure let is rejected during parsing In the original stabilization PR, @ `compiler-errors` has [pointed out](rust-lang/rust#94927 (comment)) that #97295 wasn't enough to address the concerns about having `let` in expressions being rejected at parsing time, instead of later. Thankfully, since then the situation has been greatly improved by #115677. This PR adds some additional tests to `disallowed-positions.rs`, and adds two additional revisions to the "normal" case which is now given the `feature` name: * `no_feature`: Added to incorporate `disallowed-positions-without-feature-gate.rs` into the file, reducing duplication. * `nothing`: like feature, but all functions are cfg'd out. Ensures that the errors are really emitted during parsing. cc tracking issue #53667
…compiler-errors Additional tests to ensure let is rejected during parsing In the original stabilization PR, @ `compiler-errors` has [pointed out](rust-lang#94927 (comment)) that rust-lang#97295 wasn't enough to address the concerns about having `let` in expressions being rejected at parsing time, instead of later. Thankfully, since then the situation has been greatly improved by rust-lang#115677. This PR adds some additional tests to `disallowed-positions.rs`, and adds two additional revisions to the "normal" case which is now given the `feature` name: * `no_feature`: Added to incorporate `disallowed-positions-without-feature-gate.rs` into the file, reducing duplication. * `nothing`: like feature, but all functions are cfg'd out. Ensures that the errors are really emitted during parsing. cc tracking issue rust-lang#53667
Stabilization proposal
This PR proposes the stabilization of
#![feature(let_chains)]
in a future-compatibility way that will allow the possible addition of theEXPR is PAT
syntax.Tracking issue: #53667
Version: 1.64 (beta => 2022-08-11, stable => 2022-10-22).
What is stabilized
The ability to chain let expressions along side local variable declarations or ordinary conditional expressions. For example:
Motivation
The main motivation for this feature is improving readability, ergonomics and reducing paper cuts.
For more examples, see the RFC.
What isn't stabilized
Let chains in match guards (
if_let_guard
)Resolution of divergent non-terminal matchers
The
EXPR is PAT
syntaxHistory
if let
expressionsenhanced_binary_op
featurelet_chains
andif_let_guard
feature flagslet_chains
let_else
withlet_chains
let_chains
let_chains
let_chains
let_chains
let_chains
let_chains
let_chains
let_chains
let_chains
||
in let chain expressionsFrom the first RFC (2017-12-24) to the theoretical future stabilization day (2022-10-22), it can be said that this feature took 4 years, 9 months and 28 days of research, development, discussions, agreements and headaches to be settled.
Divergent non-terminal matchers
More specifically, #86730.
To the best of my knowledge, such error or divergence is orthogonal, does not prevent stabilization and can be tackled independently in the near future or effectively in the next Rust 2024 edition. If not, then https://github.com/c410-f3r/rust/tree/let-macro-blah contains a set of changes that will consider
let
an expression.It is possible that none of the solutions above satisfies all applicable constraints but I personally don't know of any other plausible answers.
Alternative syntax
Taking into account the usefulness of this feature and the overwhelming desire to use both now and in the past,
let PAT = EXPR
will be utilized for stabilization but it doesn't or shall create any obstacle for a possible future addition ofEXPR is PAT
.The introductory snippet would then be written as the following.
Just to reinforce, this PR only unblocks a possible future road for
EXPR is PAT
and does emphasize what is better or what is worse.Tests
Verifies the drop order of let chains and ensures it won't change in the future in an unpredictable way
AST lowering does not wrap let chains in an
DropTemps
expressionChecks pretty printing output
Verifies uninitialized variables due to MIR modifications
A collection of statements where
let
expressions are forbiddenAll or at least most of the places where let chains are allowed
Ensures that irrefutable lets are allowed in let chains
issue-88498.rs, issue-90722.rs, issue-92145.rs and issue-93150.rs were bugs found by third parties and fixed overtime.
Indexing was triggering a ICE due to a wrongly constructed MIR graph
Protects the precedence of
&&
in relation to other thingslet_chains
, as well asif_let_guard
, has a valid MIR graph that evaluates conditional expressions correctlyMost of the infra-structure used by let chains is also used by
if
expressions in stable compiler versions since #80357 and #88572. As a result, no bugs were found since the integration of #88642.Possible future work
Let chains in match guards is implemented and working but stabilization is blocked by
if_let_guard
.The usage of
let_chains
withlet_else
is possible but not implemented. Regardless, one attempt was introduced and closed in [WIP] Introduceast::StmtKind::LetElse
to allow the usage oflet_else
withlet_chains
#93437.Thanks @Centril for creating the RFC and huge thanks (again) to @matthewjasper for all the reviews, mentoring and MIR implementations.
Fixes #53667