Why this fires¶
A value whose type is a union can be used without narrowing only through the members shared by every alternative. Otherwise the call or field read could be valid for one runtime value and invalid for another.
struct User { name: str }
struct Team { title: str }
fn label(value: User | Team) -> str {
return value.name
// ^ error[TE486]: `name` is missing on Team
}TE486 also fires when every alternative has a same-named method but their parameter lists are incompatible.
Fix it¶
Narrow the value with match or an is guard before using an alternative-
specific member:
fn label(value: User | Team) -> str {
if value is User {
return value.name
}
return (value as Team).title
}If the operation is conceptually shared, give each type a field or method with
the same contract. A common field may return different types; Zolo preserves
that information as another normalized union instead of widening it to Any.
Notes¶
- Union order is not semantic:
User | TeamandTeam | Userare the same type. - Nested unions are flattened and duplicate alternatives are removed.
- A common method must have compatible required arguments and parameter types.
- The runtime representation is unchanged; this check is erased after type checking.
See also¶
specs/casting-and-conversions.html— explicit casts and checked casts.specs/gradual-type-precision.html— normative union and narrowing rules.