diff --git a/src/nouveau/compiler/nak/ir_proc.rs b/src/nouveau/compiler/nak/ir_proc.rs index 4f9ad615468..371aafd8bd7 100644 --- a/src/nouveau/compiler/nak/ir_proc.rs +++ b/src/nouveau/compiler/nak/ir_proc.rs @@ -14,12 +14,98 @@ use syn::*; #[proc_macro_derive(SrcsAsSlice, attributes(src_type))] pub fn derive_srcs_as_slice(input: TokenStream) -> TokenStream { - derive_as_slice(input, "Src", "src_type", "SrcType") + let input2 = input.clone(); + let DeriveInput { ident, data, .. } = parse_macro_input!(input2); + + if let Data::Enum(e) = data { + let mut as_slice_cases = TokenStream2::new(); + let mut as_mut_slice_cases = TokenStream2::new(); + let mut types_cases = TokenStream2::new(); + for v in e.variants { + let case = v.ident; + as_slice_cases.extend(quote! { + #ident::#case(x) => x.srcs_as_slice(), + }); + as_mut_slice_cases.extend(quote! { + #ident::#case(x) => x.srcs_as_mut_slice(), + }); + types_cases.extend(quote! { + #ident::#case(x) => x.src_types(), + }); + } + quote! { + impl SrcsAsSlice for #ident { + fn srcs_as_slice(&self) -> &[Src] { + match self { + #as_slice_cases + } + } + + fn srcs_as_mut_slice(&mut self) -> &mut [Src] { + match self { + #as_mut_slice_cases + } + } + + fn src_types(&self) -> SrcTypeList { + match self { + #types_cases + } + } + } + } + .into() + } else { + derive_as_slice(input, "Src", "src_type", "SrcType") + } } #[proc_macro_derive(DstsAsSlice, attributes(dst_type))] pub fn derive_dsts_as_slice(input: TokenStream) -> TokenStream { - derive_as_slice(input, "Dst", "dst_type", "DstType") + let input2 = input.clone(); + let DeriveInput { ident, data, .. } = parse_macro_input!(input2); + + if let Data::Enum(e) = data { + let mut as_slice_cases = TokenStream2::new(); + let mut as_mut_slice_cases = TokenStream2::new(); + let mut types_cases = TokenStream2::new(); + for v in e.variants { + let case = v.ident; + as_slice_cases.extend(quote! { + #ident::#case(x) => x.dsts_as_slice(), + }); + as_mut_slice_cases.extend(quote! { + #ident::#case(x) => x.dsts_as_mut_slice(), + }); + types_cases.extend(quote! { + #ident::#case(x) => x.dst_types(), + }); + } + quote! { + impl DstsAsSlice for #ident { + fn dsts_as_slice(&self) -> &[Dst] { + match self { + #as_slice_cases + } + } + + fn dsts_as_mut_slice(&mut self) -> &mut [Dst] { + match self { + #as_mut_slice_cases + } + } + + fn dst_types(&self) -> DstTypeList { + match self { + #types_cases + } + } + } + } + .into() + } else { + derive_as_slice(input, "Dst", "dst_type", "DstType") + } } #[proc_macro_derive(DisplayOp)]