Is there a known best idiom for enforcing that a generic type is a struct type and not a class? We have AnyObject for enforcing a class but I don't think there is anything like this for structs, is there?
The usecase is a package that needs a State type that can be observed (via @Observable). Internally, the package wraps the generic type provided by the package user in an @Observable class but observation won't work unless the State property is a struct, right?
I can put together something Mirror-based or a macro perhaps that the package code uses to fail compilation. Is there anything else that is simpler/more elegant/builtin-ish that I may be missing?
A struct constraint wouldn't help in this scenario as a struct can just wrap a mutable class and you will have the same problem again. The obvious next idea of making it a recursive requirement of all store properties is too strict because it is possible to implement a struct that wraps a class in a way that @Observable can observe changes. All container types like String, Array, Set, Dictionary etc. do exactly that.
What you probably want is something that is often referred to as a "value semantics" constraint or "value types" although I don't think we ever landed on a formal definition of the term. Generally the idea of such a constraint would be that all mutations need to go through a mutating access (which is what @Observable picks up through the set/_modify accessor) and otherwise the value can't change.
Edit: For @Observable this would actually be too restrictive as well as other classes that also use @Observable are actually fine and work with the observation system.
_isPOD and the BitwiseCopyable protocol are options but IMO probably too restrictive as well to be really useful for restricting what can be used in @State/@Observable. If you can't use String, Array or any other dynamically sized data structure in your model you will not get very far.
I just wanted to ensure that there are no surprises and observation works for the State provided by the client of the package. As you said, documenting the requirement may just be enough.