Expand description
Traits and types used for tracking the usage of generic parameters through a proc-macro input.
When generating trait impls, libraries often want to automatically figure out which type parameters are used in which fields, and then emit bounds that will produce the most permissive compilable code.
Usage
Example 1: Filtering
This example accepts a proc-macro input, then finds all lifetimes and type parameters used by private fields.
fn process(input: &DeriveInput) -> Generics {
let type_params = input.generics.declared_type_params();
let lifetimes = input.generics.declared_lifetimes();
let mut ret_generics = input.generics.clone();
if let Data::Struct(ref body) = input.data {
let internal_fields = body
.fields
.iter()
.filter(|field| field.vis == Visibility::Inherited)
.collect::<Vec<_>>();
let int_type_params = internal_fields
.collect_type_params(&Purpose::BoundImpl.into(), &type_params);
// We could reuse the vec from above, but here we'll instead
// directly consume the chained iterator.
let int_lifetimes = body
.fields
.iter()
.filter(|field| field.vis == Visibility::Inherited)
.collect_lifetimes(&Purpose::BoundImpl.into(), &lifetimes);
ret_generics.params = ret_generics
.params
.into_iter()
.filter(|gp| {
match *gp {
GenericParam::Type(ref ty) => int_type_params.contains(&ty.ident),
GenericParam::Lifetime(ref lt) => int_lifetimes.contains(<.lifetime),
_ => true,
}
})
.collect();
}
ret_generics
}
Example 2: Integrating with FromDeriveInput
It is possible to use darling
’s magic fields feature in tandem with the usage
feature set.
While there is no custom derive for UsesTypeParams
or UsesLifetimes
, there are macros to
generate impls.
#![allow(dead_code)]
#[derive(FromField)]
#[darling(attributes(speak))]
struct SpeakerField {
ident: Option<syn::Ident>,
ty: syn::Type,
#[darling(default)]
volume: Option<u32>,
}
uses_type_params!(SpeakerField, ty);
uses_lifetimes!(SpeakerField, ty);
#[derive(FromDeriveInput)]
struct SpeakerOptions {
generics: syn::Generics,
data: darling::ast::Data<darling::util::Ignored, SpeakerField>,
}
At this point, you are able to call uses_type_params
on SpeakerOptions.data
, or any filtered
view of it. darling
internally uses this in conjunction with the skip
meta-item to determine
which type parameters don’t require the FromMeta
bound in generated impls.
Note: If you are performing operations referencing generic params in meta-items parsed by darling
,
you should determine if those impact the emitted code and wire up UsesTypeParams
accordingly for
your field/variant.
Structs
Control struct for searching type parameters.
Enums
The goal of tracing generic parameter usage.
Traits
Searcher for finding lifetimes in an iterator.
Searcher for finding type params in an iterator.
Extension trait for pulling specific generics data from a generics AST representation.
Searcher for finding lifetimes in a syntax tree. This can be used to determine which lifetimes must be emitted in generated code.
Searcher for finding type params in a syntax tree. This can be used to determine if a given type parameter needs to be bounded in a generated impl.
Type Definitions
A set of references to idents.
A set of idents.
A set of references to lifetimes.
A set of lifetimes.