Matching on concerete type within a generic trait: unreachable_patterns

I've isolated the following from a more elaborate context.

What is the correct way to match on whether C or D are being used for the generic type B?

struct C {};
struct D {};
impl TraitB for C {}
impl TraitB for D {}

impl<A, B> GenericTrait<A> for B
where A: TraitA,
      B: TraitB,
{
    fn plain(&mut self, a: &A) {
        match self {
            C => {
                ...
                },
            D => {
               ...
                },
        }
    }
}
   |
79 |             C => {
   |             - matches any value
...
82 |             D => {
   |             ^ unreachable pattern
   |
   = note: `#[warn(unreachable_patterns)]` on by default

The answer is either:

  • Stop using a trait, and use an enum COrD { C(C), D(D) }, or
  • Rather than trying to match, call something on a trait that's implemented with the required behaviour for C and D.

(This is basically the same answer as "stop using is chains; use virtual functions" in Java.)

2 Likes