How to mark Non-ZST?

I have the error:

transparent struct needs at most one non-zero-sized field, but has 2

I understand that reason is restriction, such structure cant have 2 ZST, but how to express such restriction with traits?

Code:

#[repr(transparent)]
pub struct ix2<E: Sized>(E, E);

Playground

You can have as many ZSTs as you want, but only one non-ZST. Incidentally, Sized is implied in that position.


There's no standard trait bound for being a ZST or not. You could maybe hack one together with const generics but I don't think there's a way to get the compiler to recognize it for e.g. the #[repr(transparent)] requirements.

2 Likes

Oh.. so it's opposite. Where can I read about repr(transparent)]? Does Sized imply that the type is non-ZST?

Check out the Other Reprs chapter from the Rust Nomicon. It also has a section on Exotically Sized Types (ZSTs, Sized, etc.).

2 Likes

Here and the RFC it links to.

No, Sized implies that the size is known at compile time. ZSTs are sized (and their size is 0). DSTs (Dynamically Sized Types) like str and [T] and dyn Trait are not Sized because they can have many different sizes, varying at runtime.

The Sized bound is implied on most generic type parameter positions. You can remove the bound by using <T: ?Sized>. The main place it is not implied is for the implementer of a trait; that is,

trait Trait {}

has no Sized supertrait bound; non-Sized types can implement Trait.

1 Like

Thanks. It makes sense to me.