diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index a3148fdb184..e526dc48d9c 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -1362,39 +1362,15 @@ impl MacroParse for syn::ItemConst { impl MacroParse for syn::ItemForeignMod { fn macro_parse(self, program: &mut ast::Program, opts: BindgenAttrs) -> Result<(), Diagnostic> { let mut errors = Vec::new(); - match self.abi.name { - Some(ref l) if l.value() == "C" => {} - None => {} - Some(ref other) => { - errors.push(err_span!( - other, - "only foreign mods with the `C` ABI are allowed" - )); - } + if let Some(other) = self.abi.name.filter(|l| l.value() != "C") { + errors.push(err_span!( + other, + "only foreign mods with the `C` ABI are allowed" + )); } - let module = if let Some((name, span)) = opts.module() { - if opts.inline_js().is_some() { - let msg = "cannot specify both `module` and `inline_js`"; - errors.push(Diagnostic::span_error(span, msg)); - } - if opts.raw_module().is_some() { - let msg = "cannot specify both `module` and `raw_module`"; - errors.push(Diagnostic::span_error(span, msg)); - } - Some(ast::ImportModule::Named(name.to_string(), span)) - } else if let Some((name, span)) = opts.raw_module() { - if opts.inline_js().is_some() { - let msg = "cannot specify both `raw_module` and `inline_js`"; - errors.push(Diagnostic::span_error(span, msg)); - } - Some(ast::ImportModule::RawNamed(name.to_string(), span)) - } else if let Some((js, span)) = opts.inline_js() { - let i = program.inline_js.len(); - program.inline_js.push(js.to_string()); - Some(ast::ImportModule::Inline(i, span)) - } else { - None - }; + let module = module_from_opts(program, &opts) + .map_err(|e| errors.push(e)) + .unwrap_or_default(); for item in self.items.into_iter() { if let Err(e) = item.macro_parse(program, module.clone()) { errors.push(e); @@ -1439,6 +1415,38 @@ impl MacroParse> for syn::ForeignItem { } } +pub fn module_from_opts( + program: &mut ast::Program, + opts: &BindgenAttrs, +) -> Result, Diagnostic> { + let mut errors = Vec::new(); + let module = if let Some((name, span)) = opts.module() { + if opts.inline_js().is_some() { + let msg = "cannot specify both `module` and `inline_js`"; + errors.push(Diagnostic::span_error(span, msg)); + } + if opts.raw_module().is_some() { + let msg = "cannot specify both `module` and `raw_module`"; + errors.push(Diagnostic::span_error(span, msg)); + } + Some(ast::ImportModule::Named(name.to_string(), span)) + } else if let Some((name, span)) = opts.raw_module() { + if opts.inline_js().is_some() { + let msg = "cannot specify both `raw_module` and `inline_js`"; + errors.push(Diagnostic::span_error(span, msg)); + } + Some(ast::ImportModule::RawNamed(name.to_string(), span)) + } else if let Some((js, span)) = opts.inline_js() { + let i = program.inline_js.len(); + program.inline_js.push(js.to_string()); + Some(ast::ImportModule::Inline(i, span)) + } else { + None + }; + Diagnostic::from_vec(errors)?; + Ok(module) +} + /// Get the first type parameter of a generic type, errors on incorrect input. fn extract_first_ty_param(ty: Option<&syn::Type>) -> Result, Diagnostic> { let t = match ty {