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 does not compile #9647

Closed
haata opened this issue Oct 14, 2022 · 3 comments · Fixed by #9685
Closed

collapsible_match suggestion does not compile #9647

haata opened this issue Oct 14, 2022 · 3 comments · Fixed by #9685
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied

Comments

@haata
Copy link

haata commented Oct 14, 2022

Summary

collapisble_match warning gives an incorrect suggestion for code that cannot compile. Even with some tweaks, I haven't been able to compress the statement.

I suspect the syn crate may be doing something interesting, but I haven't investigated it deeply.

Lint Name

collapsible_match

Reproducer

I tried this code:

use syn::{parse, Field, Type, Expr, Result, ExprLit, Lit, TypePath};

pub fn parse_type(field: &Field, ft: Type) -> Result<(TypePath, usize)> {
    match ft {
        Type::Array(a) => {
            let mut size: usize = 0;

            if let Expr::Lit(ExprLit { lit, .. }) = a.len {
                if let  = lit {
                    if let Ok(num) = lit.base10_parse::<usize>() {
                        size = num;
                    }
                }
            }
            if size == 0 {
                Err(
                    parse::Error::new(field.ident.as_ref().unwrap().span(), "`#[gen_hid_descriptor]` array has invalid length")
                )
            } else {
                Ok((parse_type(field, *a.elem)?.0, size))
            }
        }
        Type::Path(p) => {
            Ok((p, 1))
        }
        _ => {
            Err(
                parse::Error::new(field.ident.as_ref().unwrap().span(),"`#[gen_hid_descriptor]` cannot handle field type")
            )
        }
    }
}

I saw this happen:

warning: this `if let` can be collapsed into the outer `if let`
  --> src/main.rs:13:17
   |
13 | /                 if let Lit::Int(lit) = lit {
14 | |                     if let Ok(num) = lit.base10_parse::<usize>() {
15 | |                         size = num;
16 | |                     }
17 | |                 }
   | |_________________^
   |
help: the outer pattern can be modified to include the inner pattern
  --> src/main.rs:12:40
   |
12 |             if let Expr::Lit(ExprLit { lit, .. }) = a.len {
   |                                        ^^^ replace this binding
13 |                 if let Lit::Int(lit) = lit {
   |                        ^^^^^^^^^^^^^ 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

warning: `collapsible_match` (bin "collapsible_match") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.09s

I changed the code to the suggestion:

            if let Expr::Lit(ExprLit { Lit::Int(lit), .. }) = a.len {
                    if let Ok(num) = lit.base10_parse::<usize>() {
                        size = num;
                    }
            }

This happened:

    Checking collapsible_match v0.1.0 (/home/hyatt/git/examples/collapsible_match)
error: expected `,`
  --> src/main.rs:11:43
   |
11 |             if let Expr::Lit(ExprLit { Lit::Int(lit), .. }) = a.len {
   |                              -------      ^^
   |                              |
   |                              while parsing the fields for this pattern

error[E0425]: cannot find value `lit` in this scope
   --> src/main.rs:12:38
    |
12  |                     if let Ok(num) = lit.base10_parse::<usize>() {
    |                                      ^^^ help: a function with a similar name exists: `Lit`
    |
   ::: /home/hyatt/.cargo/registry/src/github.com-1ecc6299db9ec823/syn-1.0.102/src/lit.rs:733:1
    |
733 | pub fn Lit(marker: lookahead::TokenMarker) -> Lit {
    | ------------------------------------------------- similarly named function `Lit` defined here

warning: unused import: `Lit`
 --> src/main.rs:1:54
  |
1 | use syn::{parse, Field, Type, Expr, Result, ExprLit, Lit, TypePath};
  |                                                      ^^^
  |
  = note: `#[warn(unused_imports)]` on by default

For more information about this error, try `rustc --explain E0425`.
warning: `collapsible_match` (bin "collapsible_match") generated 1 warning
error: could not compile `collapsible_match` due to 2 previous errors; 1 warning emitted

Version

rustc 1.66.0-nightly (6b3ede3f7 2022-10-13)
binary: rustc
commit-hash: 6b3ede3f7bc502eba7bbd202b4b9312d812adcd7
commit-date: 2022-10-13
host: x86_64-unknown-linux-gnu
release: 1.66.0-nightly
LLVM version: 15.0.2

Additional Labels

@rustbot label +l-suggestion-causes-error

@haata haata added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Oct 14, 2022
@rustbot
Copy link
Collaborator

rustbot commented Oct 14, 2022

Error: Label l-suggestion-causes-error can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.

@Alexendoo Alexendoo added the I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied label Oct 15, 2022
@kraktus
Copy link
Contributor

kraktus commented Oct 15, 2022

correct suggestion should be

if let Expr::Lit(ExprLit { lit: Lit::Int(lit), .. }) = a.len {
                    if let Ok(num) = lit.base10_parse::<usize>() {
                        size = num;
                    }
            }

@kraktus
Copy link
Contributor

kraktus commented Oct 15, 2022

mini repro playground:

pub enum X {
    A { a: Option<u8>, b: () },
    B,
}

pub fn repro(x: X) {
    if let X::A { a, .. } = x {
        if let Some(u) = a {
            println!("{u}")
        }
    }
}

/*pub fn current_suggestion(x: X) {
    if let X::A { Some(u), .. } = x {
        println!("{u}")
    }
}
pub fn expected_suggestion(x: X) {
    if let X::A { a: Some(u), .. } = x {
        println!("{u}")
    }
}*/

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-false-positive Issue: The lint was triggered on code it shouldn't have I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants