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);
6 s.bind_with(|_| synstructure::BindStyle::Move);
8 let tcx: syn::Lifetime = parse_quote!('tcx);
9 let newtcx: syn::GenericParam = parse_quote!('__lifted);
13 let ident = &ast.ident;
15 // Replace `'tcx` lifetime by the `'__lifted` lifetime
16 let (_, generics, _) = ast.generics.split_for_impl();
17 let mut generics: syn::AngleBracketedGenericArguments = syn::parse_quote! { #generics };
18 for arg in generics.args.iter_mut() {
20 syn::GenericArgument::Lifetime(l) if *l == tcx => {
21 *arg = parse_quote!('__lifted);
23 syn::GenericArgument::Type(t) => {
24 *arg = syn::parse_quote! { #t::Lifted };
30 quote! { #ident #generics }
33 let body = s.each_variant(|vi| {
34 let bindings = &vi.bindings();
35 vi.construct(|_, index| {
36 let bi = &bindings[index];
37 quote! { __tcx.lift(#bi)? }
41 s.add_impl_generic(newtcx);
43 quote!(::rustc_middle::ty::Lift<'__lifted>),
45 type Lifted = #lifted;
47 fn lift_to_tcx(self, __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>) -> Option<#lifted> {
48 Some(match self { #body })