E3051

E3051 — A match pattern that names a variant of another enum than the value matched, such as Other::Red in a match on a Color. Write the variant with the matched value's enum.

What the compiler reports

Error[E3051] at [[@LINE+1]]:5: this pattern is a variant of `Other`, but the value matched is a `Color`; write `Color::Red`
Error[E2003] at [[@LINE+1]]:5: Unknown enum Nonsense
Error[E2004] at [[@LINE+1]]:5: Enum Color does not have variant Green
Error[E3051] at [[@LINE+1]]:5: this pattern is a variant of `Other`, but the value matched is a `Color`; write `Color::Red`
4 error(s) emitted

The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.

A program that triggers it

//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
// A variant pattern must name the matched value's enum and one of its variants. The compiler
// used to look at the variant name only, so `Other::Red` and `Nonsense::Blue(n)` matched a
// `Color`, and `Color::Green` was accepted although `Color` has no `Green`.

enum Color {
  Red,
  Blue(i64),
}

enum Other {
  Red,
  Blue(i64),
}

fn by_value(c : Color) -> i64 {
  match c {
    Other::Red => {
      return 1;
    }
    Nonsense::Blue(n) => {
      return n;
    }
  }
}

fn missing_variant(c : Color) -> i64 {
  match c {
    Color::Red => {
      return 1;
    }
    Color::Green => {
      return 2;
    }
    Color::Blue(n) => {
      return n;
    }
  }
}

fn by_reference(c : &Color) -> i64 {
  match c {
    Other::Red => {
      return 1;
    }
    _ => {
      return 0;
    }
  }
}

fn main() -> i32 {
  let c : Color = Color::Blue(4);
  print(by_value(c));
  return 0;
}

From tests/frontend/fail/match_pattern_names_the_wrong_enum.vx, which asserts this diagnostic on every commit.

Related