That would be unsound. For example, types that implement the unsafe Pod
trait mustn't have padding bytes. (u8 | u64)
would automatically implement Pod
, even though it can have padding.
Even if we excluded unsafe traits, I doubt that it would be sound. However, I could imagine a concept similar to auto traits. Let's call them composable traits for now:
composable trait Foo {}
impl Foo for i32 {}
impl Foo for &str {}
// (i32 | &str) implements Foo
Unlike auto traits, composable traits may have methods and associated types and constants. Note that neither auto traits nor composable traits need to be lang items @H2CO3.
I agree with @H2CO3 that this is a pretty radical change that would require a separate RFC. When you write an RFC for anonymous enums, you can add it to the "Future possibilities" section.
I don't think that's a good idea, for two reasons. First, it breaks type inference:
if foo {
0usize
} else {
1 // this should be an usize
}
Second, it is implicit and can cause confusion, for example:
fn return_iter() -> impl Iterator<Item = i32> {
if foo {
vec![1, 2, 3].into_iter()
} else {
std::iter::once(42)
}
}
Assuming that Iterator
is composable, this would compile fine. However, it is not at all obvious that it returns an anonymous enum, since the branches have different types.
I think it would be better to make the coercion explicit:
fn return_iter() -> impl Iterator<Item = i32> {
if foo {
vec![1, 2, 3].into_iter() as (IntoIter | _)
} else {
std::iter::once(42) as (Once | _)
}
}
FYI f
and u
aren't valid suffixes, you need to write 1f32
and 2usize
.