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
A tour of VxThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E3036A static call to a method several traits supply, where no impl takes the argument types written. Reported instead of an ambiguity (E3035), because ambiguity is not what went wrong: the call named one thing and the arguments ruled every candidate out. The message lists the impls that do exist, which is the edit.
E3021An enum variant whose payload is a tensor. A payload is stored into the variant's tagged-union slot with
llvm.insertvalue, which takes primitive operands, and a tensor is a memref descriptor. The AST path dropped such a payload silently: the construction emitted the tag and nothing else, so a program carrying a tensor through an enum compiled, ran, and lost it with no diagnostic. A struct field holding a tensor is the same representational gap in another position.