• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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