-
Notifications
You must be signed in to change notification settings - Fork 28
Add skip_type_params attribute
#96
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
Conversation
test_suite/tests/derive.rs
Outdated
|
|
||
| let ty = Type::builder() | ||
| .path(Path::new("Hey", "derive")) | ||
| .type_params(tuple_meta_type!(u16)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems to me more correct to me to have the first type param marked as skipped than ignored, otherwise when looking at the metadata and the doc of the rust type we can't easily tell which one is skipped and which one is kept
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean like .composite(Fields::named().field(|f| f.ty::<Greet<SomeType>>().name("ciao").type_name("Greet<T>").skipped_type_params::<T>())?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually I'm not sure anymore, I don't understand enough the usecase for type_params.
But what I meant is that currently the Hey<SomeType, u16> type information about type params would be u16, whereas I would have expected "skipped", u16.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point, we are losing some information by removing it entirely. I have addressed this by adding a TypeParameter struct with Option<MetaType> which would be None for skipped type params. Addressed in 411e50c
test_suite/tests/derive.rs
Outdated
|
|
||
| let ty = Type::builder() | ||
| .path(Path::new("Hey", "derive")) | ||
| .type_params(tuple_meta_type!(u16)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean like .composite(Fields::named().field(|f| f.ty::<Greet<SomeType>>().name("ciao").type_name("Greet<T>").skipped_type_params::<T>())?
skip_type_params attributeskip_type_params attribute
|
Meeting idea/proposal: #[derive(TypeInfo)]
#[scale_info(bounds(U: TypeInfo + 'static))]
#[scale_info(skip_type_params(T))]
struct S<T, U> {
marker: PhantomData<T>,
field: U,
}We could write this: #[derive(TypeInfo)]
#[scale_info(bounds(
U: TypeInfo + 'static,
T = skip,
))]
struct S<T, U> {
marker: PhantomData<T>,
field: U,
} |
| /// | ||
| /// `#[scale_info(bounds(..))]` | ||
| /// | ||
| /// Replaces *all* auto-generated trait bounds with the user-defined ones. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[scale_info(skip_type_params(U))]
#[scale_info(bounds("U: Other + Traits + NotTypeInfoStuff))]
struct A<T, U> { … }In the above, I will not get TypeInfo bounds auto-generated for T (because bounds() override all auto generating machinery) but I will get the bounds I manually specified for U (because bounds(…) trumps skip_type_params). Is that correct?
A few examples like above would be good! :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the above, I will not get TypeInfo bounds auto-generated for T (because bounds() override all auto generating machinery) but I will get the bounds I manually specified for U (because bounds(…) trumps skip_type_params). Is that correct?
Correct. It trumps it in respect to the generated where clause. However skip_type_params still has its effect on the generated list of type_params for the type.
A few examples like above would be good! :)
I am in the process of adding more rustdocs on the topic, in the meantime I have added some more ui tests and have updated the PR description.
With This makes it unsuitable for the use case in substrate where we add
Also this would break the parsing of |
Currently the
TypeInfoderive adds all generic type params to theType::type_paramsmetadata.Therefore all type params must be constrained to
TypeInfoin order for the call tometa_typeto compile. So the proc macro automatically adds those bounds.However, sometimes this requirement forces us to implement
TypeInfoor provide additional bounds where it is unnecessary.This PR introduces the
skip_type_paramsattribute, which removes the requirement for the supplied type params to implementTypeInfo.Scenario 1:
skip_type_paramson its own.Consider a simple example of a type parameter which is used for associated types, but the type itself does not carry any type information. This is a common pattern in substrate:
Without
skip_type_params, the following code is generated:With the
skip_type_paramsappliedNote how in the above we still get the autogenerated bounds for the associated type
T::AScenario 2:
skip_type_paramsused in conjunction withbounds.#88 adds support for specifying custom bounds, which overrides all auto generated bounds. Without
skip_type_params, it is therefore required that the user manually addsT: TypeInfoto the custom bounds attribute.Adding
skip_type_paramsmeans that we no longer need to add the unnecessary bound to our custom bounds.How
boundsandskip_type_paramsinteract.When used independently, both attributes have an effect of the
whereclause predicate of the generatedTypeInfoimpl block.boundsreplaces all autogenerated bounds with the user supplied ones in the attributeskip_type_paramsprevents theTypeInfobound for the given type params being added to the autogenerated bounds.When they are both used together,
skip_type_paramshas no effect on the final generatedwhereclause at all, because the predicates supplied inboundsare used verbatim instead of any autogenerated bounds.