diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index f53cbb9c..e3788a2c 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -291,11 +291,13 @@ impl ToTokens for ast::StructField { let ty = &self.ty; let getter = &self.getter; let setter = &self.setter; + + let assert_copy = quote! { assert_copy::<#ty>() }; + let assert_copy = respan(assert_copy, ty); (quote! { - #[no_mangle] #[doc(hidden)] - #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] #[allow(clippy::all)] + #[cfg_attr(all(target_arch = "wasm32", not(target_os = "emscripten")), no_mangle)] pub unsafe extern "C" fn #getter(js: u32) -> <#ty as wasm_bindgen::convert::IntoWasmAbi>::Abi { @@ -303,7 +305,7 @@ impl ToTokens for ast::StructField { use wasm_bindgen::convert::{GlobalStack, IntoWasmAbi}; fn assert_copy(){} - assert_copy::<#ty>(); + #assert_copy; let js = js as *mut WasmRefCell<#struct_name>; assert_not_null(js); @@ -714,7 +716,8 @@ impl ToTokens for ast::ImportType { () }; - }).to_tokens(tokens); + }) + .to_tokens(tokens); let deref_target = match self.extends.first() { Some(target) => quote! { #target }, @@ -1430,3 +1433,31 @@ impl<'a, T: ToTokens> ToTokens for Descriptor<'a, T> { .to_tokens(tokens); } } + +fn respan( + input: TokenStream, + span: &dyn ToTokens, +) -> TokenStream { + let mut first_span = Span::call_site(); + let mut last_span = Span::call_site(); + let mut spans = TokenStream::new(); + span.to_tokens(&mut spans); + + for (i, token) in spans.into_iter().enumerate() { + if i == 0 { + first_span = token.span(); + } + last_span = token.span(); + } + + let mut new_tokens = Vec::new(); + for (i, mut token) in input.into_iter().enumerate() { + if i == 0 { + token.set_span(first_span); + } else { + token.set_span(last_span); + } + new_tokens.push(token); + } + new_tokens.into_iter().collect() +} diff --git a/crates/macro/ui-tests/pub-not-copy.rs b/crates/macro/ui-tests/pub-not-copy.rs new file mode 100644 index 00000000..4c7cf0b3 --- /dev/null +++ b/crates/macro/ui-tests/pub-not-copy.rs @@ -0,0 +1,10 @@ +#![crate_type = "rlib"] + +extern crate wasm_bindgen; + +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub struct A { + pub field: String, +} diff --git a/crates/macro/ui-tests/pub-not-copy.stderr b/crates/macro/ui-tests/pub-not-copy.stderr new file mode 100644 index 00000000..95b597c4 --- /dev/null +++ b/crates/macro/ui-tests/pub-not-copy.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied + --> $DIR/pub-not-copy.rs:9:16 + | +9 | pub field: String, + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` + | +note: required by `__wbg_get_a_field::assert_copy` + --> $DIR/pub-not-copy.rs:7:1 + | +7 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.