3 use syn::{self, parse_quote};
6 pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
7 s.add_bounds(synstructure::AddBounds::Generics);
9 let tcx: syn::Lifetime = parse_quote!('tcx);
10 let newtcx: syn::GenericParam = parse_quote!('__lifted);
14 let ident = &ast.ident;
16 // Replace `'tcx` lifetime by the `'__lifted` lifetime
17 let (_, generics, _) = ast.generics.split_for_impl();
18 let mut generics: syn::AngleBracketedGenericArguments = syn::parse_quote! { #generics };
19 for arg in generics.args.iter_mut() {
21 syn::GenericArgument::Lifetime(l) if *l == tcx => {
22 *arg = parse_quote!('__lifted);
24 syn::GenericArgument::Type(t) => {
25 *arg = syn::parse_quote! { #t::Lifted };
31 quote! { #ident #generics }
34 let body = s.each_variant(|vi| {
35 let bindings = &vi.bindings();
36 vi.construct(|_, index| {
37 let bi = &bindings[index];
38 quote! { __tcx.lift(#bi)? }
42 s.add_impl_generic(newtcx);
44 quote!(::rustc::ty::Lift<'__lifted>),
46 type Lifted = #lifted;
48 fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__lifted>) -> Option<#lifted> {
49 Some(match *self { #body })