rust-lang / rust-lang/rust-analyzer

Non-semantic preserving transform from replace_match_with_if_let

Open
#17,008 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

rust-analyzer version: (eg. output of "rust-analyzer: Show RA Version" command, accessible in VSCode via Ctrl/⌘+Shift+P)

rust-analyzer version: 0.3.1906-standalone (e4a405f87 2024-03-31)

rustc version: (eg. output of rustc -V)

rustc 1.77.1 (7cf61ebde 2024-03-27)

editor or extension: (eg. VSCode, Vim, Emacs, etc. For VSCode users, specify your extension version; for users of other editors, provide the distribution if applicable)

helix 24.3 (d56f3fb7)

relevant settings: (eg. client settings, or environment variables like CARGO, RUSTC, RUSTUP_HOME or CARGO_HOME)

I don't think there's any relevant settings

code snippet to reproduce:

pub fn test(input: Result<u8, ()>) {
    match input {
        Ok(0) => (),
        Ok(_) | Err(_) => some_code(),
    }
}

Put your cursor on the match statement and select Replace match with if let. This transforms the above in to:

@@ -1,6 +1,5 @@
 pub fn test(input: Result<u8, ()>) {
-    match input {
-        Ok(0) => (),
-        Ok(_) | Err(_) => some_code(),
+    if let Ok(_) | Err(_) = input {
+        some_code()
     }
 }

Which obviously does not preserve the semantics of the original program. I would expect something similar to the following transformation:

@@ -1,6 +1,5 @@
 pub fn test(input: Result<u8, ()>) {
-    match input {
-        Ok(0) => (),
-        Ok(_) | Err(_) => some_code(),
+    if let Ok(0) = input {} else {
+        some_code()
     }
 }

This looks similar to #11547 but seems to do with the or pattern.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the supplied Rust snippet in rust-analyzer and invoke the “Replace match with if let” action from the match statement. Trace the transformation entry point for this assist and add a regression case showing that the resulting code preserves the original match semantics, including the or-pattern; done means the expected if-let/else form is produced.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.