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

unnecessary_parens false positive when calling function from match #90456

Closed
monoclex opened this issue Oct 31, 2021 · 3 comments
Closed

unnecessary_parens false positive when calling function from match #90456

monoclex opened this issue Oct 31, 2021 · 3 comments
Labels
C-bug Category: This is a bug.

Comments

@monoclex
Copy link

Rust Information

rustc --version: rustc 1.55.0-nightly (gentoo)
rustfmt --version: rustfmt 1.4.37-nightly ( )
cargo --version: cargo 1.55.0-nightly
rust-analyzer version: v0.3.794 preview (nightly mode is enabled)

Repro

pub enum Repro {
    A(i64),
    B(i64),
}

fn make(a: bool, data: i64) -> Repro {
    (match a {
        true => Repro::A,
        false => Repro::B,
    }(data))
}

Issue

When I write my code as suggested, I get a warning for putting parenthesis around this match statement:

the warning

However, upon doing what the warning says, I am then greeted with a compiler error (the error persists if I put the parenthesis next to the closing brace of the match statement, as expected)

the compiler error

@jieyouxu
Copy link
Member

This is interesting because

pub enum Repro {
    A(i64),
    B(i64),
}

fn make(a: bool, data: i64) -> Repro {
    let enum_variant_constructor_fn_ptr: fn(i64) -> Repro = match a {
        true => Repro::A,
        false => Repro::B,
    };
    enum_variant_constructor_fn_ptr(data)
}

is fine, and

pub enum Repro {
    A(i64),
    B(i64),
}

fn make(a: bool, data: i64) -> Repro {
    (match a {
        true => Repro::A,
        false => Repro::B,
    })(data)
}

is also fine since enum variants are? fn-pointers fn(i64) -> Repro.

I think the issue here is not warning the user with a match expression immediately following parenthesized expression? I.e. constructs of the form doesn't seem right:

match <expr> { ... } ( <expr> )

There's caveats to this too: consider zero-variant enums:

enum Never {}

fn test() -> Never {
    match true {
        _ => Never
    }()
}

do not trigger this combo:

   Compiling playground v0.0.1 (/playground)
error[E0423]: expected value, found enum `Never`
 --> src/lib.rs:5:14
  |
5 |         _ => Never
  |              ^^^^^
  |
note: the enum is defined here
 --> src/lib.rs:1:1
  |
1 | enum Never {}
  | ^^^^^^^^^^^^^
help: consider importing one of these items instead
  |
1 | use csv::QuoteStyle::Never;
  |
1 | use csv_core::QuoteStyle::Never;
  |
1 | use env_logger::WriteStyle::Never;
  |
1 | use syn::Type::Never;
  |
    and 1 other candidate

error[E0308]: mismatched types
 --> src/lib.rs:6:6
  |
3 | fn test() -> Never {
  |              ----- expected `Never` because of return type
...
6 |     }()
  |      ^^ expected enum `Never`, found `()`

Some errors have detailed explanations: E0308, E0423.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors

So smaller examples that triggers this combo...

...with 1-variant enum:

enum Single {
    A(())
}

fn test() -> Single {
    match true {
        _ => Single::A
    }(())
}

...or with tuple-struct:

struct A(());

fn test() -> A {
    match true {
        _ => A
    }(())
}

since their variant/member initializer fns can be cast? into fn pointers.

@ghost
Copy link

ghost commented Oct 31, 2021

Looks like a duplicate of #88519.

@ehuss
Copy link
Contributor

ehuss commented Nov 1, 2021

Thanks for the report! Yea, I believe this is a duplicate of #88519, and should be fixed in 1.57.

@ehuss ehuss closed this as completed Nov 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants