E3020

E3020 — A match that no arm is guaranteed to match. A match over an enum must name every variant or carry a wildcard arm, wherever it sits. The uncovered value falls through, and when every written arm returns, the function falls off its end and hands back whatever was in the return slot. A scrutinee that is not an enum cannot be enumerated, so it is only asked for a wildcard in value position, where the fall-through edge would otherwise have no value to carry — codegen used to paper over that by evaluating the whole match to a constant zero.

What the compiler reports

E3020 … does not cover Blue … add an arm for each, or a `_` arm

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 `match` used as a value has to produce one on every path. This one names
// two of `Color`'s three variants and has no wildcard, so `Blue` falls through
// with nothing to yield.
//
// The refusal names the variant that is missing, because that is the edit: add
// the arm, or add a `_`. Codegen used to answer the whole match with a constant
// zero, which made the missing case indistinguishable from an arm returning 0.
//
// The statement-position form of the same match is refused too, for a reason
// this file does not cover: see match_missing_a_variant_falls_off_the_end.vx.
//

enum Color {
  Red, Green, Blue
}

fn main() -> i32 {
  let c = Color::Blue;
  let x = match c {
    Color::Red => {
      1
    }
    Color::Green => {
      42
    }
  };
  return x;
}

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

Related