1use crate::syntax::instantiate::NamedImplKey; 2use crate::syntax::resolve::Resolution; 3use crate::syntax::{Impl, Lifetimes}; 4use proc_macro2::TokenStream; 5use quote::ToTokens; 6use syn::{Lifetime, Token}; 7 8pub struct ImplGenerics<'a> { 9 explicit_impl: Option<&'a Impl>, 10 resolve: Resolution<'a>, 11} 12 13pub struct TyGenerics<'a> { 14 key: NamedImplKey<'a>, 15 explicit_impl: Option<&'a Impl>, 16 resolve: Resolution<'a>, 17} 18 19pub fn split_for_impl<'a>( 20 key: NamedImplKey<'a>, 21 explicit_impl: Option<&'a Impl>, 22 resolve: Resolution<'a>, 23) -> (ImplGenerics<'a>, TyGenerics<'a>) { 24 let impl_generics = ImplGenerics { 25 explicit_impl, 26 resolve, 27 }; 28 let ty_generics = TyGenerics { 29 key, 30 explicit_impl, 31 resolve, 32 }; 33 (impl_generics, ty_generics) 34} 35 36impl<'a> ToTokens for ImplGenerics<'a> { 37 fn to_tokens(&self, tokens: &mut TokenStream) { 38 if let Some(imp) = self.explicit_impl { 39 imp.impl_generics.to_tokens(tokens); 40 } else { 41 self.resolve.generics.to_tokens(tokens); 42 } 43 } 44} 45 46impl<'a> ToTokens for TyGenerics<'a> { 47 fn to_tokens(&self, tokens: &mut TokenStream) { 48 if let Some(imp) = self.explicit_impl { 49 imp.ty_generics.to_tokens(tokens); 50 } else if !self.resolve.generics.lifetimes.is_empty() { 51 let span = self.key.rust.span(); 52 self.key 53 .lt_token 54 .unwrap_or_else(|| Token) 55 .to_tokens(tokens); 56 self.resolve.generics.lifetimes.to_tokens(tokens); 57 self.key 58 .gt_token 59 .unwrap_or_else(|| Token) 60 .to_tokens(tokens); 61 } 62 } 63} 64 65pub struct UnderscoreLifetimes<'a> { 66 generics: &'a Lifetimes, 67} 68 69impl Lifetimes { 70 pub fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes { 71 UnderscoreLifetimes { generics: self } 72 } 73} 74 75impl<'a> ToTokens for UnderscoreLifetimes<'a> { 76 fn to_tokens(&self, tokens: &mut TokenStream) { 77 let Lifetimes { 78 lt_token, 79 lifetimes, 80 gt_token, 81 } = self.generics; 82 lt_token.to_tokens(tokens); 83 for pair in lifetimes.pairs() { 84 let (lifetime, punct) = pair.into_tuple(); 85 let lifetime = Lifetime::new("'_", lifetime.span()); 86 lifetime.to_tokens(tokens); 87 punct.to_tokens(tokens); 88 } 89 gt_token.to_tokens(tokens); 90 } 91} 92