Idea: Default method of comparing enum variants with data

#1

It is currently possible to compare enum variants that don’t have any data attached with PartialEq:

example:

#[derive(PartialEq)]
enum Var {
    A,
    B,
    C
}

fn foobar(c: Var) -> bool {
    c == Var::C
}

It is also possible to use pattern matching and bypass the requirement for PartialEq but is very cumbersome and doesn’t read very well:

example:

enum Var {
    A,
    B,
    C
}

fn foobar(c: Var) -> bool {
    if let Var::C = c { true } else { false }
}

However, pattern matching is really the only way to do it if any of the enum variants have data because then the inner types also have to implement PartialEq. This is also undesirable because some value would then have to be constructed on the left hand side (the side that you want to compare to not the value you are wishing to compare with). And that is just unnecessary.

example:

enum Var {
    A(i32),
    B(u32),
    C(bool)
}

fn foobar(c: Var) -> bool {
    if let Var::C(..) = c { true } else { false }
}

Possible Options:

  1. Do nothing: this problem is solvable in user space it is just not smooth
  2. Allow .. or _ in variant comparisons: This would be the smoothest for the user to use but be much more difficult for the compiler team.
  3. Proc-Macro: This would use mem::discriminant and mem::uninitialized to do the comparison but I am unsure of how the use case would be because Var::c(mem::uninitialized()) == c does not look like something that should be promoted.
  4. Discriminant Value: Allow non-complete enum variants to be equal to their discriminant`

Analysis:

I believe that option 4 is the best both in terms of most sound and easiest to implement. No need for new traits, operators, or macros. Plus it is decently clear what it would mean to someone who hadn’t seen it already.

0 Likes

#2

https://docs.rs/matches/*/matches/macro.matches.html

0 Likes

#3

Thank you, that does help and probably points to only doing option 1

0 Likes