You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The impl iroha_schema_derive generates a has incorrect trait bounds inferred: O: Identifiable + IntoSchema, while in reality what it needs is O: Identifiable + TypeId, O::Id: IntoSchema (that is, TypeId type parameters and IntoSchema on types used in the fields).
This is also a problem for std derives and serde.
The simplistic algorithm that only involves the type parameters is used in compiler-builtin derives, as well as in a lot of ecosystem crates (like serde). It's my understanding that this is mostly done because doing it correctly was hard due to limitations in trait type-checking (rust-lang/rust#26925, serde-rs/serde#2463).
In both serde and iroha_schema_derive there is an escape hatch that lets you specify the trait bounds manually. For std derives, there are crates that allow you to do this (for example derive-where).
Specifying trait bounds manually is not ideal, but works well enough for hand-written types. When using macro_rules! it's basically impossible though, since it requires generating string literals and passing then to attr macros. This is currently blocking me from implementing query projections (#5063)
parity_scale_codec has an algorithm that actually looks at the fields of structures it works on, and in most cases generates more correct bounds. There are still some issues with it, but they are much more mild. As a testament to parity_scale_codec's approach robustness: we did not have to use any of the escape hatch mechanisms provided (#[codec(dumb_trait_bound)], #[codec(encode_bound)], #[codec(decode_bound)], #[codec(mel_bound)]) by them in any of the iroha code.
The (local) solution
The solution, in the context of #5063, is twofold:
The problem & its context
In a lot of cases an automatically-derived trait bound is not correct.
For example:
The impl
iroha_schema_derive
generates a has incorrect trait bounds inferred:O: Identifiable + IntoSchema
, while in reality what it needs isO: Identifiable + TypeId, O::Id: IntoSchema
(that is,TypeId
type parameters andIntoSchema
on types used in the fields).This is also a problem for
std
derives andserde
.The simplistic algorithm that only involves the type parameters is used in compiler-builtin derives, as well as in a lot of ecosystem crates (like
serde
). It's my understanding that this is mostly done because doing it correctly was hard due to limitations in trait type-checking (rust-lang/rust#26925, serde-rs/serde#2463).In both
serde
andiroha_schema_derive
there is an escape hatch that lets you specify the trait bounds manually. Forstd
derives, there are crates that allow you to do this (for examplederive-where
).Specifying trait bounds manually is not ideal, but works well enough for hand-written types. When using
macro_rules!
it's basically impossible though, since it requires generating string literals and passing then to attr macros. This is currently blocking me from implementing query projections (#5063)parity_scale_codec
has an algorithm that actually looks at the fields of structures it works on, and in most cases generates more correct bounds. There are still some issues with it, but they are much more mild. As a testament toparity_scale_codec
's approach robustness: we did not have to use any of the escape hatch mechanisms provided (#[codec(dumb_trait_bound)]
,#[codec(encode_bound)]
,#[codec(decode_bound)]
,#[codec(mel_bound)]
) by them in any of the iroha code.The (local) solution
The solution, in the context of #5063, is twofold:
iroha_schema_derive
, which we control, use the trait bound generation algorithm fromparity_scale_codec
: refactor(schema_derive): use a smarter algorithm for auto-generated trait bounds #5132serde
, which we don't control, and it doesn't seem likely that this issue will be remedied soon (associated types and bounds serde-rs/serde#2784, Review the bounds generation heuristic? serde-rs/serde#2463, Trait bounds for deserialization are enforced even if deserialization is skipped. serde-rs/serde#2736, Skip serializing generic still requires the bound serde-rs/serde#2727), the best solution I can come up with is to make a helper proc macro that will generate the right#[serde(bounds(...))]
with a similar algorithmThe text was updated successfully, but these errors were encountered: