1 use crate::syntax::instantiate::NamedImplKey;
2 use crate::syntax::resolve::Resolution;
3 use crate::syntax::{Impl, Lifetimes};
4 use proc_macro2::TokenStream;
5 use quote::ToTokens;
6 use syn::{Lifetime, Token};
7
8 pub struct ImplGenerics<'a> {
9 explicit_impl: Option<&'a Impl>,
10 resolve: Resolution<'a>,
11 }
12
13 pub struct TyGenerics<'a> {
14 key: NamedImplKey<'a>,
15 explicit_impl: Option<&'a Impl>,
16 resolve: Resolution<'a>,
17 }
18
split_for_impl<'a>( key: NamedImplKey<'a>, explicit_impl: Option<&'a Impl>, resolve: Resolution<'a>, ) -> (ImplGenerics<'a>, TyGenerics<'a>)19 pub 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
36 impl<'a> ToTokens for ImplGenerics<'a> {
to_tokens(&self, tokens: &mut TokenStream)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
46 impl<'a> ToTokens for TyGenerics<'a> {
to_tokens(&self, tokens: &mut TokenStream)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![<](span))
55 .to_tokens(tokens);
56 self.resolve.generics.lifetimes.to_tokens(tokens);
57 self.key
58 .gt_token
59 .unwrap_or_else(|| Token![>](span))
60 .to_tokens(tokens);
61 }
62 }
63 }
64
65 pub struct UnderscoreLifetimes<'a> {
66 generics: &'a Lifetimes,
67 }
68
69 impl Lifetimes {
to_underscore_lifetimes(&self) -> UnderscoreLifetimes70 pub fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes {
71 UnderscoreLifetimes { generics: self }
72 }
73 }
74
75 impl<'a> ToTokens for UnderscoreLifetimes<'a> {
to_tokens(&self, tokens: &mut TokenStream)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