Description
Feature
Currently, #[derive(ComponentType)]
etc. requires that all generic struct parameters directly and unconditionally implement ComponentType
. It would be useful to be able to specify custom bounds for the trait impl, similar to #[serde(bounds = "...")]
.
Benefit
I'm the author of glamour, a strongly typed vector math library. My vector types have a Unit
generic param, and all the fields of the vector are defined in terms of an associated type Unit::Scalar
, which is always a primitive. So for Vector4<T>
, the T
only appears in the struct as T::Scalar
(which always implements Lower + Lift
), but T
itself does not implement Lower + Lift
.
The current derive macros mean that only the "untyped" units (plain scalar types, such as Vector4<f32>
) can implement ComponentType
etc., which is unfortunate - it would be nice to be able to leverage this kind of type safety in automatically generated WIT bindings.
More generally, this would provide an escape hatch for some of the problems with "imperfect derive".
Implementation
I would propose extending the derive macro to support a #[component(bounds = ...)]
attribute at the container level for structs and enums, replacing the implicit T: ComponentType
bound (same for Lower
and Lift
derives).
Alternatives
- The derive macro can be amended to emit an impl that is bounded on the specific field types of the struct, i.e., collect all field types and add bounds for each type that appears as a field. This may be less attractive because it reveals internal things about the type, potentially making it more brittle (semver hazard).
- Currently it is not feasible/possible to manually implement
ComponentType
/Lower
/Lift
. That API could be stabilized, allowing users to handle the problem themselves.