-
Notifications
You must be signed in to change notification settings - Fork 30
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
Add skip_type_params
attribute
#96
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
TypeInfo
derive adds all generic type params to theType::type_params
metadata.Therefore all type params must be constrained to
TypeInfo
in order for the call tometa_type
to compile. So the proc macro automatically adds those bounds.However, sometimes this requirement forces us to implement
TypeInfo
or provide additional bounds where it is unnecessary.This PR introduces the
skip_type_params
attribute, which removes the requirement for the supplied type params to implementTypeInfo
.Scenario 1:
skip_type_params
on 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_params
appliedNote how in the above we still get the autogenerated bounds for the associated type
T::A
Scenario 2:
skip_type_params
used 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: TypeInfo
to the custom bounds attribute.Adding
skip_type_params
means that we no longer need to add the unnecessary bound to our custom bounds.How
bounds
andskip_type_params
interact.When used independently, both attributes have an effect of the
where
clause predicate of the generatedTypeInfo
impl block.bounds
replaces all autogenerated bounds with the user supplied ones in the attributeskip_type_params
prevents theTypeInfo
bound for the given type params being added to the autogenerated bounds.When they are both used together,
skip_type_params
has no effect on the final generatedwhere
clause at all, because the predicates supplied inbounds
are used verbatim instead of any autogenerated bounds.