Skip to content

Commit e4400ac

Browse files
committed
Improve error message for non-copy struct fields
Make sure the error message points to the type in question instead of to the `#[wasm_bindgen]` macro which can be overly confusing!
1 parent 16745ed commit e4400ac

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

crates/backend/src/codegen.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,19 +291,21 @@ impl ToTokens for ast::StructField {
291291
let ty = &self.ty;
292292
let getter = &self.getter;
293293
let setter = &self.setter;
294+
295+
let assert_copy = quote! { assert_copy::<#ty>() };
296+
let assert_copy = respan(assert_copy, ty);
294297
(quote! {
295-
#[no_mangle]
296298
#[doc(hidden)]
297-
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
298299
#[allow(clippy::all)]
300+
#[cfg_attr(all(target_arch = "wasm32", not(target_os = "emscripten")), no_mangle)]
299301
pub unsafe extern "C" fn #getter(js: u32)
300302
-> <#ty as wasm_bindgen::convert::IntoWasmAbi>::Abi
301303
{
302304
use wasm_bindgen::__rt::{WasmRefCell, assert_not_null};
303305
use wasm_bindgen::convert::{GlobalStack, IntoWasmAbi};
304306

305307
fn assert_copy<T: Copy>(){}
306-
assert_copy::<#ty>();
308+
#assert_copy;
307309

308310
let js = js as *mut WasmRefCell<#struct_name>;
309311
assert_not_null(js);
@@ -714,7 +716,8 @@ impl ToTokens for ast::ImportType {
714716

715717
()
716718
};
717-
}).to_tokens(tokens);
719+
})
720+
.to_tokens(tokens);
718721

719722
let deref_target = match self.extends.first() {
720723
Some(target) => quote! { #target },
@@ -1430,3 +1433,31 @@ impl<'a, T: ToTokens> ToTokens for Descriptor<'a, T> {
14301433
.to_tokens(tokens);
14311434
}
14321435
}
1436+
1437+
fn respan(
1438+
input: TokenStream,
1439+
span: &dyn ToTokens,
1440+
) -> TokenStream {
1441+
let mut first_span = Span::call_site();
1442+
let mut last_span = Span::call_site();
1443+
let mut spans = TokenStream::new();
1444+
span.to_tokens(&mut spans);
1445+
1446+
for (i, token) in spans.into_iter().enumerate() {
1447+
if i == 0 {
1448+
first_span = token.span();
1449+
}
1450+
last_span = token.span();
1451+
}
1452+
1453+
let mut new_tokens = Vec::new();
1454+
for (i, mut token) in input.into_iter().enumerate() {
1455+
if i == 0 {
1456+
token.set_span(first_span);
1457+
} else {
1458+
token.set_span(last_span);
1459+
}
1460+
new_tokens.push(token);
1461+
}
1462+
new_tokens.into_iter().collect()
1463+
}

crates/macro/ui-tests/pub-not-copy.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![crate_type = "rlib"]
2+
3+
extern crate wasm_bindgen;
4+
5+
use wasm_bindgen::prelude::*;
6+
7+
#[wasm_bindgen]
8+
pub struct A {
9+
pub field: String,
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
2+
--> $DIR/pub-not-copy.rs:9:16
3+
|
4+
9 | pub field: String,
5+
| ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
6+
|
7+
note: required by `__wbg_get_a_field::assert_copy`
8+
--> $DIR/pub-not-copy.rs:7:1
9+
|
10+
7 | #[wasm_bindgen]
11+
| ^^^^^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)