Currently there's some workarounds to deal with multiple error types other than creating a sum type, like dyn or anyhow.
The idea here is to make the compiler generate this sum type and allow transparent construction and matching.
union Error = Utf8Error | ParseIntError;
// translates to
// enum Error { _anon0(Utf8Error), _anon1(ParseIntError) }
fn convert(bytes: &[u8]) -> Result<i32, Error> {
let s = std::str::from_utf8(bytes)?; // auto-wraps into Error
let n: i32 = s.trim().parse()?; // auto-wraps into Error
Ok(n)
}
match convert(bytes) {
Ok(n) => println!("{n}"),
Err(err @ Utf8Error) => { .. }
Err(err @ ParseIntError) => { .. }
}
Since it compiles down to a regular enum type, it would be a 'safe' union type compared to the one currently available.
Note that nested unions get flattened out,
union X = A | B;
union Y = C | D;
union Z = X | Y;
// translates to
// enum Z { _anon0(A), _anon1(B), _anon2(C), _anon3(D), }
which is considerably simpler to match as in match z { A | B | C | D => {} }.