133d722a9Sopenharmony_ciuse crate::syntax::instantiate::NamedImplKey;
233d722a9Sopenharmony_ciuse crate::syntax::resolve::Resolution;
333d722a9Sopenharmony_ciuse crate::syntax::{Impl, Lifetimes};
433d722a9Sopenharmony_ciuse proc_macro2::TokenStream;
533d722a9Sopenharmony_ciuse quote::ToTokens;
633d722a9Sopenharmony_ciuse syn::{Lifetime, Token};
733d722a9Sopenharmony_ci
833d722a9Sopenharmony_cipub struct ImplGenerics<'a> {
933d722a9Sopenharmony_ci    explicit_impl: Option<&'a Impl>,
1033d722a9Sopenharmony_ci    resolve: Resolution<'a>,
1133d722a9Sopenharmony_ci}
1233d722a9Sopenharmony_ci
1333d722a9Sopenharmony_cipub struct TyGenerics<'a> {
1433d722a9Sopenharmony_ci    key: NamedImplKey<'a>,
1533d722a9Sopenharmony_ci    explicit_impl: Option<&'a Impl>,
1633d722a9Sopenharmony_ci    resolve: Resolution<'a>,
1733d722a9Sopenharmony_ci}
1833d722a9Sopenharmony_ci
1933d722a9Sopenharmony_cipub fn split_for_impl<'a>(
2033d722a9Sopenharmony_ci    key: NamedImplKey<'a>,
2133d722a9Sopenharmony_ci    explicit_impl: Option<&'a Impl>,
2233d722a9Sopenharmony_ci    resolve: Resolution<'a>,
2333d722a9Sopenharmony_ci) -> (ImplGenerics<'a>, TyGenerics<'a>) {
2433d722a9Sopenharmony_ci    let impl_generics = ImplGenerics {
2533d722a9Sopenharmony_ci        explicit_impl,
2633d722a9Sopenharmony_ci        resolve,
2733d722a9Sopenharmony_ci    };
2833d722a9Sopenharmony_ci    let ty_generics = TyGenerics {
2933d722a9Sopenharmony_ci        key,
3033d722a9Sopenharmony_ci        explicit_impl,
3133d722a9Sopenharmony_ci        resolve,
3233d722a9Sopenharmony_ci    };
3333d722a9Sopenharmony_ci    (impl_generics, ty_generics)
3433d722a9Sopenharmony_ci}
3533d722a9Sopenharmony_ci
3633d722a9Sopenharmony_ciimpl<'a> ToTokens for ImplGenerics<'a> {
3733d722a9Sopenharmony_ci    fn to_tokens(&self, tokens: &mut TokenStream) {
3833d722a9Sopenharmony_ci        if let Some(imp) = self.explicit_impl {
3933d722a9Sopenharmony_ci            imp.impl_generics.to_tokens(tokens);
4033d722a9Sopenharmony_ci        } else {
4133d722a9Sopenharmony_ci            self.resolve.generics.to_tokens(tokens);
4233d722a9Sopenharmony_ci        }
4333d722a9Sopenharmony_ci    }
4433d722a9Sopenharmony_ci}
4533d722a9Sopenharmony_ci
4633d722a9Sopenharmony_ciimpl<'a> ToTokens for TyGenerics<'a> {
4733d722a9Sopenharmony_ci    fn to_tokens(&self, tokens: &mut TokenStream) {
4833d722a9Sopenharmony_ci        if let Some(imp) = self.explicit_impl {
4933d722a9Sopenharmony_ci            imp.ty_generics.to_tokens(tokens);
5033d722a9Sopenharmony_ci        } else if !self.resolve.generics.lifetimes.is_empty() {
5133d722a9Sopenharmony_ci            let span = self.key.rust.span();
5233d722a9Sopenharmony_ci            self.key
5333d722a9Sopenharmony_ci                .lt_token
5433d722a9Sopenharmony_ci                .unwrap_or_else(|| Token![<](span))
5533d722a9Sopenharmony_ci                .to_tokens(tokens);
5633d722a9Sopenharmony_ci            self.resolve.generics.lifetimes.to_tokens(tokens);
5733d722a9Sopenharmony_ci            self.key
5833d722a9Sopenharmony_ci                .gt_token
5933d722a9Sopenharmony_ci                .unwrap_or_else(|| Token![>](span))
6033d722a9Sopenharmony_ci                .to_tokens(tokens);
6133d722a9Sopenharmony_ci        }
6233d722a9Sopenharmony_ci    }
6333d722a9Sopenharmony_ci}
6433d722a9Sopenharmony_ci
6533d722a9Sopenharmony_cipub struct UnderscoreLifetimes<'a> {
6633d722a9Sopenharmony_ci    generics: &'a Lifetimes,
6733d722a9Sopenharmony_ci}
6833d722a9Sopenharmony_ci
6933d722a9Sopenharmony_ciimpl Lifetimes {
7033d722a9Sopenharmony_ci    pub fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes {
7133d722a9Sopenharmony_ci        UnderscoreLifetimes { generics: self }
7233d722a9Sopenharmony_ci    }
7333d722a9Sopenharmony_ci}
7433d722a9Sopenharmony_ci
7533d722a9Sopenharmony_ciimpl<'a> ToTokens for UnderscoreLifetimes<'a> {
7633d722a9Sopenharmony_ci    fn to_tokens(&self, tokens: &mut TokenStream) {
7733d722a9Sopenharmony_ci        let Lifetimes {
7833d722a9Sopenharmony_ci            lt_token,
7933d722a9Sopenharmony_ci            lifetimes,
8033d722a9Sopenharmony_ci            gt_token,
8133d722a9Sopenharmony_ci        } = self.generics;
8233d722a9Sopenharmony_ci        lt_token.to_tokens(tokens);
8333d722a9Sopenharmony_ci        for pair in lifetimes.pairs() {
8433d722a9Sopenharmony_ci            let (lifetime, punct) = pair.into_tuple();
8533d722a9Sopenharmony_ci            let lifetime = Lifetime::new("'_", lifetime.span());
8633d722a9Sopenharmony_ci            lifetime.to_tokens(tokens);
8733d722a9Sopenharmony_ci            punct.to_tokens(tokens);
8833d722a9Sopenharmony_ci        }
8933d722a9Sopenharmony_ci        gt_token.to_tokens(tokens);
9033d722a9Sopenharmony_ci    }
9133d722a9Sopenharmony_ci}
92