2 use syn::{self, parse_quote};
4 pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
5 s.add_bounds(synstructure::AddBounds::Generics);
7 let tcx: syn::Lifetime = parse_quote!('tcx);
8 let newtcx: syn::GenericParam = parse_quote!('__lifted);
12 let ident = &ast.ident;
14 // Replace `'tcx` lifetime by the `'__lifted` lifetime
15 let (_, generics, _) = ast.generics.split_for_impl();
16 let mut generics: syn::AngleBracketedGenericArguments = syn::parse_quote! { #generics };
17 for arg in generics.args.iter_mut() {
19 syn::GenericArgument::Lifetime(l) if *l == tcx => {
20 *arg = parse_quote!('__lifted);
22 syn::GenericArgument::Type(t) => {
23 *arg = syn::parse_quote! { #t::Lifted };
29 quote! { #ident #generics }
32 let body = s.each_variant(|vi| {
33 let bindings = &vi.bindings();
34 vi.construct(|_, index| {
35 let bi = &bindings[index];
36 quote! { __tcx.lift(#bi)? }
40 s.add_impl_generic(newtcx);
42 quote!(::rustc_middle::ty::Lift<'__lifted>),
44 type Lifted = #lifted;
46 fn lift_to_tcx(&self, __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>) -> Option<#lifted> {
47 Some(match *self { #body })