I don't think there's a way without nesting an actual type in there. And that may hurt size optimization.
pub struct FooB { x: u32, y: f32, }
pub enum Foo {
A((u32, f32)),
B(FooB),
}
pub fn f(foo: Foo) {
match foo {
Foo::A(a) => println!("{} {}", a.0, a.1),
Foo::B(b) => println!("{} {}", b.x, b.y),
}
}
Inside the arm, a
and b
need to have a type. So Rust would need "variants are types" (not holding my breath), or
- Automatic conversion between tuple variants and tuples
- So their layouts must also match
- Ad-hoc structs (with named fields)
- Automatic conversion between struct variants and ad-hoc structs
- So their layouts must also match
Or perhaps some sort of view struct like helper that applies when you know the variant.
The layout thing is a big deal as a repr(Rust)
variant need not be contiguous, say (ala the size example). Other repr
s have C++ or C-like guarantees, but they don't line up in the tuple case, since all anonymous tuples are repr(Rust)
. So maybe add "ad-hoc anonymous tuple types" to the list if things went that way. (Also not holding my breath something like this would be added just for non-repr(Rust)
enum
s though.)
There's other use-case specific possibilities like some coordinated union and enum with unsafe
, or a C-like enum as a sibling to your data if all your field types match, etc.
match f {
obj @ A => { obj.0; obj.1; },
obj @ B => { obj.x; obj.y; },
}
The type of a variant is the type of the enum, and enum's aren't unions, so that won't work.