Skip to content

collapsible_match suggestion does not compile #9647

Closed
@haata

Description

@haata

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.colasdn.workers.dev-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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't haveI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions