There was a lengthy discussion: Ideas around anonymous enum types and an rfc which suggested syntax like
let x = (i32 | &str)::0(1_i32);
match x {
(_ | _)::0(val) => ...,
(_ | _)::1(_) => unreachable!("...")
};
and I think in it was suggested a generic parameter in obvious cases would be translated into this ::0 or ::1 as appropriate. So this problem is solvable.
We were considering a &dyn (A|B) which was a fat pointer consisting of discriminant and reference to actual data and &dyn (A|B) was cheaply coersable to &dyn (A|B|C) - the coercion just entailed a change of the discriminant (part of fat pointer) but not of the data..
But it isn't really possible to coerce &dyn mut (A|B) to &dyn mut (A|B|C) as C may require more space than either A or B. Also if I remember correctly it wasn't obvious how to represent &dyn u8|Trait. This "fat" pointer would go super-fat: it would gain both discriminant and a pointer to the type's vtable.
Main motivation for these exercises was to return errors nicely: say child function can return Err1|Err2 but parent wants to return Err1|Err2|Err3 and we want to avoid expensive operation of copying memory around.. That has never been solved. It would have required some kind of a &out buffer to store data passed from the very top and it was hard to know what size of that buffer would be needed.
This prompted me to suggest a very elaborate schema that would allow functions to place values into parent/gradparent/grand^10-parent's frame but this suggestion clearly failed to gain interest ![]()