-
Notifications
You must be signed in to change notification settings - Fork 0
Deduplicated structs in codegen #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I suspect that the reason for this is likely the That all said, I'm a bit sketchy on the details and that may not be 100% accurate; we'll need to dig into this a bit more thoroughly to arrive at a proper conclusion! |
I've tried lots of combinations... When I remove pub struct X<_0> {
pub inner: ::core::primitive::u32,
#[codec(skip)]
pub __ignore: ::core::marker::PhantomData<_0>,
} |
I think one solution might be to avoid using this kind of type definition with scale_info, and instead use this pattern: struct X<Inner> { inner: Inner }
type SForT<T> = S<<T as Config>::Inner> But this seems like a shame - for one, it's ugly! And looking at the metadata, there seems to be enough information to resolve the types correctly. In fact it seems like the codegen is almost there. The types are represented in the metadata, but they have the same paths and I think the codegen is deduplicating by path. Ie. it can resolve the X { u32 } and the X { () } fine but then it deduplicates the structs at the path level. |
Mmm, I think that this is because the type information then knows that there's a generic type, but doesn't understand that the generic type has an associated type which is then used on
And yeah, from what I recall, every concrete instance of a type is represented in the metadata/type registry, and then when generating the code we have to figure out what to do with duplicates like
I can see that this would work because you keep the generic (so we know how to de-duplicate it properly) but remove the associated type link (which I think we don't have the information to deal with in Anyways, we are looking more into this anyway so we'll have a more concrete response in the next day or so; just wanted to respond sooner! |
I opened a PR that adds some checks to at least avoid that the type override happens. I think it is not really possible for us to generate a single struct |
Thanks for this! I guess my question then is, why is Also - do you know if / when / how this would be propagated to subxt codegen? |
I could go either way on this. I think that right now the reason it's not the default is becasue it messes with the type registry that's handed Currently we have a duplicate of that method in Subxt which we use instead (which is another reason we can't just call it automatically right now I think), so we'll probbaly need to break some things apart so that we can reuse this function in both places wihtout pulling in unwanted dependencies. I'll try to have a look in the next weeks, but we're going to be short on manpower for a while and have some higher priority things to focus on so it might take a while to do that bit! |
Thanks for the clarification, I totally understand. I would volunteer to help out here, but am in a similar position wrt. priorities. I'm not sure I follow what you mean regarding messing with the registry. The registry in this case clearly contains two |
With this PR, I think there will be two possible outcomes:
Without the PR, we are silently overwriting one of the types during codegen which is not ideal :) After this lands, there are some other followup things to think about:
But yeah; we are short on time/manpower and have some other priorities until end of Q2 so this might be picked up again after that! |
Yes exactly! What I'm suggesting is that that renaming the types according to some reasonable convention, while still not ideal, is "more ideal" than silently dropping one of them. I feel like both 1 and 2 are messing with the metadata in some way (1 is dropping a type, 2 is renaming). And the name of the type is not what's important: its 'shape' (and the fact it exists in the first place!) is more important than the name.
My opinion is that this is not something the codegen can ensure. If the metadata tells you "there are two distinct types at this path", then the codegen has to accept that :) |
Well, with this PR, 1 will give you an error if there would be an overlap (rather than dropping anything), and 2 will try to rename things to avoid an overlap. Only 2 actually alters the metadata though :) |
I have encountered some surprising (to me) behaviour.
I saw #13, it looks relevant but I don't understand why deduplication is the default behaviour.
The following is quite a common pattern in substrate:
The generated code is:
I would have expected either:
inner: ()
and another withinner: u32
struct X<T> { inner: T }
I can't make the codegen do this.
If first noticed the issue when using subxt codegen for Chainflip. For example for testnet:
subxt codegen --url wss://perseverance.chainflip.xyz:443
There is a type TrackedData here that has three entries in the metadata but only one in the generated code. Some similarly-defined types have multiple definitions (for example there is a type VaultRotationStatus, VaultRotationStatus2, VaultRotationStatus3). I tried to debug this and ended up digging down in to this crate.
I'm not sure if this is a bug or if i'm misusing subxt / scale-info / typegen.
Any help would be appreciated.
The text was updated successfully, but these errors were encountered: