Skip to content
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

collapsible_match suggestion incomplete #14155

Open
nk9 opened this issue Feb 5, 2025 · 0 comments
Open

collapsible_match suggestion incomplete #14155

nk9 opened this issue Feb 5, 2025 · 0 comments
Labels
C-bug Category: Clippy is not doing the correct thing I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied

Comments

@nk9
Copy link

nk9 commented Feb 5, 2025

Summary

I have the following code:

    pub fn find_railroad_name(lcomponents: &mut Vec<&str>) -> Option<String> {
        if let Some(last) = lcomponents.last() {
            match *last {
                "r.r." | "railroad" | "rr" => {
                    lcomponents.pop();
                    return Some(lcomponents.join(" "));
                }
                _ => (),
            }
        }

        None
    }

Clippy warns about this:

20  warning: this `match` can be collapsed into the outer `if let`
    --> rust/models/src/boundary_name.rs:283:13
     |
 283 | /             match *last {
 284 | |                 "r.r." | "railroad" | "rr" => {
 285 | |                     lcomponents.pop();
 286 | |                     return Some(lcomponents.join(" "));
 287 | |                 }
 288 | |                 _ => (),
 289 | |             }                                                                                                                                                                      ▐
     | |_____________^                                                                                                                                                                      ▐
     |                                                                                                                                                                                      ▐
 help: the outer pattern can be modified to include the inner pattern                                                                                                                       ▐
    --> rust/models/src/boundary_name.rs:282:21                                                                                                                                             ▐
     |                                                                                                                                                                                      ▐
 282 |         if let Some(last) = lcomponents.last() {                                                                                                                                     ▐
     |                     ^^^^ replace this binding                                                                                                                                        ▐
 283 |             match *last {                                                                                                                                                            ▐
 284 |                 "r.r." | "railroad" | "rr" => {                                                                                                                                      ▐
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ with this pattern                                                                                                                         ▐
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match                                                                      ▐
     = note: `#[warn(clippy::collapsible_match)]` on by default                                                                                                                             ▐

I tried doing what it suggested and got three compiler errors:

    pub fn find_railroad_name(lcomponents: &mut Vec<&str>) -> Option<String> {
        if let Some("r.r." | "railroad" | "rr") = lcomponents.last() {
            lcomponents.pop();
            return Some(lcomponents.join(" "));
        }

        None
    }
 1  error[E0308]: mismatched types                                                                                                                                                          ▐
    --> rust/models/src/boundary_name.rs:282:21                                                                                                                                             ▐
     |                                                                                                                                                                                      ▐
 282 |         if let Some("r.r." | "railroad" | "rr") = lcomponents.last() {                                                                                                               ▐
     |                     ^^^^^^                        ------------------ this expression has type `std::option::Option<&&str>`                                                           ▐
     |                     |                                                                                                                                                                ▐
     |                     expected `&&str`, found `&str`                                                                                                                                   ▐
     |                                                                                                                                                                                      ▐
     = note: expected reference `&&_`                                                                                                                                                       ▐
                found reference `&'static _`                                                                                                                                                ▐

What I ended up needing to do was:

    pub fn find_railroad_name(lcomponents: &mut Vec<&str>) -> Option<String> {
        if let Some(&"r.r." | &"railroad" | &"rr") = lcomponents.last() {
            lcomponents.pop();
            return Some(lcomponents.join(" "));
        }

        None
    }

It feels a little weird to be putting referenced, static strings inside a Some() pattern match like that. Anyway, I wanted to alert to the fact that the Clippy suggestion isn't sufficient in this case. Should this be special-cased, or does this actually count as a False-Positive?

Reproducer

I tried this code:

fn main() {
    let lcomponents: Vec<&str> = "B&O R.R.".to_lowercase().split_whitespace().collect();
    if let Some(rr_name) = find_railroad_name(&mut lcomponents) {
        println!("Found: {rr_name}");
    }
}

    pub fn find_railroad_name(lcomponents: &mut Vec<&str>) -> Option<String> {
        if let Some(last) = lcomponents.last() {
            match *last {
                "r.r." | "railroad" | "rr" => {
                    lcomponents.pop();
                    return Some(lcomponents.join(" "));
                }
                _ => (),
            }
        }

        None
    }

I expected to see this happen: No warning, I think? Not sure.

Instead, this happened: Warning

Version:

rustc 1.84.0 (9fc6b4312 2025-01-07)
binary: rustc
commit-hash: 9fc6b43126469e3858e2fe86cafb4f0fd5068869
commit-date: 2025-01-07
host: aarch64-apple-darwin
release: 1.84.0
LLVM version: 19.1.5

Version


Additional Labels

No response

@nk9 nk9 added the C-bug Category: Clippy is not doing the correct thing label Feb 5, 2025
@samueltardieu samueltardieu added the I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied label Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied
Projects
None yet
Development

No branches or pull requests

2 participants