diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index f244a9cd8a2..928ec8da3ed 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -150,11 +150,11 @@ impl BindgenAttrs { } /// Whether the `host_binding` attribute is present - fn host_binding(&self) -> bool { - self.attrs.iter().any(|a| match *a { - BindgenAttr::HostBinding => true, - _ => false, - }) + fn host_binding(&self) -> Option<&Ident> { + self.attrs.iter().filter_map(|a| match a { + BindgenAttr::HostBinding(i) => Some(i), + _ => None, + }).next() } /// Whether the readonly attributes is present @@ -237,7 +237,7 @@ pub enum BindgenAttr { IndexingSetter, IndexingDeleter, Structural, - HostBinding, + HostBinding(Ident), Readonly, JsName(String, Span), JsClass(String), @@ -272,7 +272,7 @@ impl Parse for BindgenAttr { return Ok(BindgenAttr::Structural); } if attr == "host_binding" { - return Ok(BindgenAttr::HostBinding); + return Ok(BindgenAttr::HostBinding(attr)) } if attr == "readonly" { return Ok(BindgenAttr::Readonly); @@ -555,13 +555,18 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option)> for syn::ForeignItemFn ShortHash(data) ) }; + if let Some(ident) = opts.host_binding() { + if opts.structural() { + bail_span!(ident, "cannot specify both `structural` and `host_binding`"); + } + } Ok(ast::ImportKind::Function(ast::ImportFunction { function: wasm, kind, js_ret, catch, variadic, - structural: opts.structural() || !opts.host_binding(), + structural: opts.structural() || opts.host_binding().is_none(), rust_name: self.ident.clone(), shim: Ident::new(&shim, Span::call_site()), doc_comment: None, diff --git a/crates/macro/ui-tests/structural-and-host-binding.rs b/crates/macro/ui-tests/structural-and-host-binding.rs new file mode 100644 index 00000000000..68bfccb41a5 --- /dev/null +++ b/crates/macro/ui-tests/structural-and-host-binding.rs @@ -0,0 +1,11 @@ +extern crate wasm_bindgen; + +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + type Foo; + + #[wasm_bindgen(method, structural, host_binding)] + fn bar(this: &Foo); +} diff --git a/crates/macro/ui-tests/structural-and-host-binding.stderr b/crates/macro/ui-tests/structural-and-host-binding.stderr new file mode 100644 index 00000000000..66e6ef670a6 --- /dev/null +++ b/crates/macro/ui-tests/structural-and-host-binding.stderr @@ -0,0 +1,8 @@ +error: cannot specify both `structural` and `host_binding` + --> $DIR/structural-and-host-binding.rs:9:40 + | +9 | #[wasm_bindgen(method, structural, host_binding)] + | ^^^^^^^^^^^^ + +error: aborting due to previous error +