@@ -168,51 +168,64 @@ fn analyze_self_and_args(sig: &Signature) -> syn::Result<MethodInfo> {
168168 }
169169 }
170170
171- if let syn:: Pat :: Ident ( pat_ident) = & * typed. pat {
172- let arg_type = & * typed. ty ;
173- let mut option_inner = None ;
174- let ref_kind = match arg_type {
175- Type :: Reference ( r) if r. mutability . is_some ( ) => Some ( RefKind :: Mut ) ,
176- Type :: Reference ( _) => Some ( RefKind :: Ref ) ,
177- _ => {
178- // Check if it's `Option<&T>` or `Option<&mut T>`
179- option_inner = try_unwrap_option ( arg_type) ;
180- option_inner. and_then ( |inner| match inner {
181- Type :: Reference ( r) if r. mutability . is_some ( ) => Some ( RefKind :: OptionMut ) ,
182- Type :: Reference ( _) => Some ( RefKind :: OptionRef ) ,
183- _ => None ,
184- } )
185- }
186- } ;
187- let callback_type = match & ref_kind {
188- Some ( RefKind :: OptionRef | RefKind :: OptionMut ) => {
189- match classify_ref_type ( option_inner. unwrap ( ) ) {
190- Some ( ty) => parse_quote ! { Option <#ty> } ,
191- None => {
192- return Err ( syn:: Error :: new_spanned (
193- arg_type,
194- "this reference type is not supported as a callback parameter" ,
195- ) ) ;
196- }
197- }
198- }
199- Some ( _) => match classify_ref_type ( arg_type) {
200- Some ( ty) => ty,
171+ let ident = match & * typed. pat {
172+ syn:: Pat :: Ident ( pat_ident) => pat_ident. ident . clone ( ) ,
173+ syn:: Pat :: Wild ( _) => {
174+ // For wildcards we generate a unique identifier to avoid collisions with other
175+ // parameters.
176+ Ident :: new ( & format ! ( "__mlua_arg_{}" , args. len( ) ) , Span2 :: mixed_site ( ) )
177+ }
178+ _ => {
179+ return Err ( syn:: Error :: new_spanned (
180+ & typed. pat ,
181+ "`#[mlua::userdata_impl]` requires a named parameter or `_`; destructuring patterns are not supported" ,
182+ ) ) ;
183+ }
184+ } ;
185+
186+ let arg_type = & * typed. ty ;
187+ let mut option_inner = None ;
188+ let ref_kind = match arg_type {
189+ Type :: Reference ( r) if r. mutability . is_some ( ) => Some ( RefKind :: Mut ) ,
190+ Type :: Reference ( _) => Some ( RefKind :: Ref ) ,
191+ _ => {
192+ // Check if it's `Option<&T>` or `Option<&mut T>`
193+ option_inner = try_unwrap_option ( arg_type) ;
194+ option_inner. and_then ( |inner| match inner {
195+ Type :: Reference ( r) if r. mutability . is_some ( ) => Some ( RefKind :: OptionMut ) ,
196+ Type :: Reference ( _) => Some ( RefKind :: OptionRef ) ,
197+ _ => None ,
198+ } )
199+ }
200+ } ;
201+ let callback_type = match & ref_kind {
202+ Some ( RefKind :: OptionRef | RefKind :: OptionMut ) => {
203+ match classify_ref_type ( option_inner. unwrap ( ) ) {
204+ Some ( ty) => parse_quote ! { Option <#ty> } ,
201205 None => {
202206 return Err ( syn:: Error :: new_spanned (
203207 arg_type,
204208 "this reference type is not supported as a callback parameter" ,
205209 ) ) ;
206210 }
207- } ,
208- None => arg_type. clone ( ) ,
209- } ;
210- args. push ( ArgInfo {
211- ident : pat_ident. ident . clone ( ) ,
212- userdata_ref : ref_kind,
213- callback_type,
214- } ) ;
215- }
211+ }
212+ }
213+ Some ( _) => match classify_ref_type ( arg_type) {
214+ Some ( ty) => ty,
215+ None => {
216+ return Err ( syn:: Error :: new_spanned (
217+ arg_type,
218+ "this reference type is not supported as a callback parameter" ,
219+ ) ) ;
220+ }
221+ } ,
222+ None => arg_type. clone ( ) ,
223+ } ;
224+ args. push ( ArgInfo {
225+ ident,
226+ userdata_ref : ref_kind,
227+ callback_type,
228+ } ) ;
216229 }
217230 }
218231 }
@@ -275,6 +288,24 @@ pub fn userdata_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
275288
276289 let mut input = parse_macro_input ! ( item as ItemImpl ) ;
277290
291+ // Generic impl blocks are not supported
292+ if !input. generics . params . is_empty ( ) {
293+ return syn:: Error :: new_spanned (
294+ & input. generics ,
295+ "`#[mlua::userdata_impl]` does not support generic impl blocks." ,
296+ )
297+ . to_compile_error ( )
298+ . into ( ) ;
299+ }
300+ if let Some ( where_clause) = & input. generics . where_clause {
301+ return syn:: Error :: new_spanned (
302+ where_clause,
303+ "`#[mlua::userdata_impl]` does not support `where` clauses on the impl block." ,
304+ )
305+ . to_compile_error ( )
306+ . into ( ) ;
307+ }
308+
278309 let type_path = match & * input. self_ty {
279310 Type :: Path ( type_path) => & type_path. path ,
280311 _ => {
0 commit comments