1 //! Traits and types used for tracking the usage of generic parameters through a proc-macro input. 2 //! 3 //! When generating trait impls, libraries often want to automatically figure out which type parameters 4 //! are used in which fields, and then emit bounds that will produce the most permissive compilable 5 //! code. 6 //! 7 //! # Usage 8 //! 9 //! ## Example 1: Filtering 10 //! This example accepts a proc-macro input, then finds all lifetimes and type parameters used 11 //! by private fields. 12 //! 13 //! ```rust 14 //! # extern crate darling_core; 15 //! # extern crate syn; 16 //! # 17 //! # // in real-world usage, import from `darling` 18 //! # use darling_core::usage::{self, CollectLifetimes, CollectTypeParams, GenericsExt, Purpose}; 19 //! # use syn::{Data, DeriveInput, GenericParam, Generics, Visibility}; 20 //! # 21 //! # #[allow(dead_code)] 22 //! fn process(input: &DeriveInput) -> Generics { 23 //! let type_params = input.generics.declared_type_params(); 24 //! let lifetimes = input.generics.declared_lifetimes(); 25 //! 26 //! let mut ret_generics = input.generics.clone(); 27 //! 28 //! if let Data::Struct(ref body) = input.data { 29 //! let internal_fields = body 30 //! .fields 31 //! .iter() 32 //! .filter(|field| field.vis == Visibility::Inherited) 33 //! .collect::<Vec<_>>(); 34 //! 35 //! let int_type_params = internal_fields 36 //! .collect_type_params(&Purpose::BoundImpl.into(), &type_params); 37 //! 38 //! // We could reuse the vec from above, but here we'll instead 39 //! // directly consume the chained iterator. 40 //! let int_lifetimes = body 41 //! .fields 42 //! .iter() 43 //! .filter(|field| field.vis == Visibility::Inherited) 44 //! .collect_lifetimes(&Purpose::BoundImpl.into(), &lifetimes); 45 //! 46 //! 47 //! ret_generics.params = ret_generics 48 //! .params 49 //! .into_iter() 50 //! .filter(|gp| { 51 //! match *gp { 52 //! GenericParam::Type(ref ty) => int_type_params.contains(&ty.ident), 53 //! GenericParam::Lifetime(ref lt) => int_lifetimes.contains(<.lifetime), 54 //! _ => true, 55 //! } 56 //! }) 57 //! .collect(); 58 //! } 59 //! 60 //! ret_generics 61 //! } 62 //! 63 //! # fn main() {} 64 //! ``` 65 //! 66 //! ## Example 2: Integrating with `FromDeriveInput` 67 //! It is possible to use `darling`'s magic fields feature in tandem with the `usage` feature set. 68 //! While there is no custom derive for `UsesTypeParams` or `UsesLifetimes`, there are macros to 69 //! generate impls. 70 //! 71 //! ```rust,ignore 72 //! #![allow(dead_code)] 73 //! 74 //! #[derive(FromField)] 75 //! #[darling(attributes(speak))] 76 //! struct SpeakerField { 77 //! ident: Option<syn::Ident>, 78 //! ty: syn::Type, 79 //! #[darling(default)] 80 //! volume: Option<u32>, 81 //! } 82 //! 83 //! uses_type_params!(SpeakerField, ty); 84 //! uses_lifetimes!(SpeakerField, ty); 85 //! 86 //! #[derive(FromDeriveInput)] 87 //! struct SpeakerOptions { 88 //! generics: syn::Generics, 89 //! data: darling::ast::Data<darling::util::Ignored, SpeakerField>, 90 //! } 91 //! ``` 92 //! 93 //! At this point, you are able to call `uses_type_params` on `SpeakerOptions.data`, or any filtered 94 //! view of it. `darling` internally uses this in conjunction with the `skip` meta-item to determine 95 //! which type parameters don't require the `FromMeta` bound in generated impls. 96 //! 97 //! **Note:** If you are performing operations referencing generic params in meta-items parsed by `darling`, 98 //! you should determine if those impact the emitted code and wire up `UsesTypeParams` accordingly for 99 //! your field/variant. 100 101 mod generics_ext; 102 mod ident_set; 103 mod lifetimes; 104 mod options; 105 mod type_params; 106 107 pub use self::generics_ext::GenericsExt; 108 pub use self::ident_set::{IdentRefSet, IdentSet}; 109 pub use self::lifetimes::{CollectLifetimes, LifetimeRefSet, LifetimeSet, UsesLifetimes}; 110 pub use self::options::{Options, Purpose}; 111 pub use self::type_params::{CollectTypeParams, UsesTypeParams}; 112