Why this fires¶
Every alternative of an or-pattern must introduce the same names with compatible types. The match body runs after any alternative succeeds, so each name it can read must exist with one stable type on every path.
enum Pick {
Left(int),
Right(int),
}
match value {
Pick::Left(left) | Pick::Right(right) => 1,
// error[TE831]: alternatives bind different names
}Reusing the same name for incompatible payload types is also rejected:
enum Value { Number(int), Text(str) }
match value {
Value::Number(inner) | Value::Text(inner) => inner,
// error[TE831]: `inner` cannot be both `int` and `str`
}Fix it¶
Bind the same name to compatible values in every alternative:
match value {
Pick::Left(inner) | Pick::Right(inner) => inner,
}If the payload types or required names differ, use separate match arms so each body has its own scope and type:
match value {
Value::Number(number) => number.to_str(),
Value::Text(text) => text,
}Notes¶
- Name comparison is set-based; source order does not need to match.
- Bindings are materialized from the alternative that actually succeeds.
- Nested tuple, enum, struct, array, rest, and
name @ patternbindings all participate in the comparison.