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