diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index 0838ad5b322..bb64914a5ef 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -376,6 +376,14 @@ impl<'a> ConvertToAst for &'a mut syn::ItemStruct { } } +fn get_ty(mut ty: &syn::Type) -> &syn::Type { + while let syn::Type::Group(g) = ty { + ty = &g.elem; + } + + ty +} + impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignItemFn { type Target = ast::ImportKind; @@ -414,7 +422,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte let class = wasm.arguments.get(0).ok_or_else(|| { err_span!(self, "imported methods must have at least one argument") })?; - let class = match &*class.ty { + let class = match get_ty(&class.ty) { syn::Type::Reference(syn::TypeReference { mutability: None, elem, @@ -425,7 +433,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte "first argument of method must be a shared reference" ), }; - let class_name = match *class { + let class_name = match get_ty(class) { syn::Type::Path(syn::TypePath { qself: None, ref path, @@ -466,7 +474,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte Some(ref ty) => ty, _ => bail_span!(self, "constructor returns must be bare types"), }; - let class_name = match *class { + let class_name = match get_ty(class) { syn::Type::Path(syn::TypePath { qself: None, ref path, @@ -666,9 +674,9 @@ fn function_from_decl( Some(i) => i, None => return t, }; - let path = match t { - syn::Type::Path(syn::TypePath { qself: None, path }) => path, - other => return other, + let path = match get_ty(&t) { + syn::Type::Path(syn::TypePath { qself: None, path }) => path.clone(), + other => return other.clone(), }; let new_path = if path.segments.len() == 1 && path.segments[0].ident == "Self" { self_ty.clone().into() @@ -869,7 +877,7 @@ impl<'a> MacroParse for &'a mut syn::ItemImpl { "#[wasm_bindgen] generic impls aren't supported" ); } - let name = match *self.self_ty { + let name = match get_ty(&self.self_ty) { syn::Type::Path(syn::TypePath { qself: None, ref path, @@ -1286,7 +1294,7 @@ fn extract_first_ty_param(ty: Option<&syn::Type>) -> Result, D Some(t) => t, None => return Ok(None), }; - let path = match *t { + let path = match *get_ty(&t) { syn::Type::Path(syn::TypePath { qself: None, ref path, @@ -1309,7 +1317,7 @@ fn extract_first_ty_param(ty: Option<&syn::Type>) -> Result, D syn::GenericArgument::Type(t) => t, other => bail_span!(other, "must be a type parameter"), }; - match ty { + match get_ty(&ty) { syn::Type::Tuple(t) if t.elems.len() == 0 => return Ok(None), _ => {} } diff --git a/crates/test-macro/src/lib.rs b/crates/test-macro/src/lib.rs index e3033c44690..0fdb7aeddd6 100644 --- a/crates/test-macro/src/lib.rs +++ b/crates/test-macro/src/lib.rs @@ -43,10 +43,7 @@ pub fn wasm_bindgen_test( } } } - let ident = match body.next() { - Some(TokenTree::Ident(token)) => token, - _ => panic!("expected a function name"), - }; + let ident = find_ident(&mut body).expect("expected a function name"); let mut tokens = Vec::::new(); @@ -78,3 +75,13 @@ pub fn wasm_bindgen_test( tokens.into_iter().collect::().into() } + +fn find_ident(iter: &mut token_stream::IntoIter) -> Option { + match iter.next()? { + TokenTree::Ident(i) => Some(i), + TokenTree::Group(g) if g.delimiter() == Delimiter::None => { + find_ident(&mut g.stream().into_iter()) + } + _ => None, + } +}