]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_macros/src/lift.rs
Add 'compiler/rustc_codegen_cranelift/' from commit '793d26047f994e23415f8f6bb5686ff2...
[rust.git] / compiler / rustc_macros / src / lift.rs
1 use quote::quote;
2 use syn::{self, parse_quote};
3
4 pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
5     s.add_bounds(synstructure::AddBounds::Generics);
6
7     let tcx: syn::Lifetime = parse_quote!('tcx);
8     let newtcx: syn::GenericParam = parse_quote!('__lifted);
9
10     let lifted = {
11         let ast = s.ast();
12         let ident = &ast.ident;
13
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() {
18             match arg {
19                 syn::GenericArgument::Lifetime(l) if *l == tcx => {
20                     *arg = parse_quote!('__lifted);
21                 }
22                 syn::GenericArgument::Type(t) => {
23                     *arg = syn::parse_quote! { #t::Lifted };
24                 }
25                 _ => {}
26             }
27         }
28
29         quote! { #ident #generics }
30     };
31
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)?  }
37         })
38     });
39
40     s.add_impl_generic(newtcx);
41     s.bound_impl(
42         quote!(::rustc_middle::ty::Lift<'__lifted>),
43         quote! {
44             type Lifted = #lifted;
45
46             fn lift_to_tcx(&self, __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>) -> Option<#lifted> {
47                 Some(match *self { #body })
48             }
49         },
50     )
51 }