diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 005f2eab460..4444d1ef6d7 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -2190,10 +2190,9 @@ impl<'a> Context<'a> { AuxExportKind::Function(_) => {} AuxExportKind::StaticFunction { .. } => {} AuxExportKind::Constructor(class) => builder.constructor(class), - AuxExportKind::Getter { .. } | AuxExportKind::Setter { .. } => { - builder.method(false) - } - AuxExportKind::Method { consumed, .. } => builder.method(*consumed), + AuxExportKind::Getter { consumed, .. } + | AuxExportKind::Setter { consumed, .. } + | AuxExportKind::Method { consumed, .. } => builder.method(*consumed), } } Kind::Import(_) => {} @@ -2257,7 +2256,7 @@ impl<'a> Context<'a> { exported.has_constructor = true; exported.push(&docs, "constructor", "", &code, ts_sig); } - AuxExportKind::Getter { class, field } => { + AuxExportKind::Getter { class, field, .. } => { let ret_ty = match export.generate_typescript { true => match &ts_ret_ty { Some(s) => Some(s.as_str()), @@ -2268,7 +2267,7 @@ impl<'a> Context<'a> { let exported = require_class(&mut self.exported_classes, class); exported.push_getter(&docs, field, &code, ret_ty); } - AuxExportKind::Setter { class, field } => { + AuxExportKind::Setter { class, field, .. } => { let arg_ty = match export.generate_typescript { true => Some(ts_arg_tys[0].as_str()), false => None, @@ -3247,20 +3246,24 @@ fn check_duplicated_getter_and_setter_names( AuxExportKind::Getter { class: first_class, field: first_field, + consumed: _, }, AuxExportKind::Getter { class: second_class, field: second_field, + consumed: _, }, ) => verify_exports(first_class, first_field, second_class, second_field)?, ( AuxExportKind::Setter { class: first_class, field: first_field, + consumed: _, }, AuxExportKind::Setter { class: second_class, field: second_field, + consumed: _, }, ) => verify_exports(first_class, first_field, second_class, second_field)?, _ => {} diff --git a/crates/cli-support/src/wit/mod.rs b/crates/cli-support/src/wit/mod.rs index 68f591ea5bc..99b11a5760b 100644 --- a/crates/cli-support/src/wit/mod.rs +++ b/crates/cli-support/src/wit/mod.rs @@ -419,6 +419,7 @@ impl<'a> Context<'a> { AuxExportKind::Getter { class, field: f.to_string(), + consumed: export.consumed, } } decode::OperationKind::Setter(f) => { @@ -426,6 +427,7 @@ impl<'a> Context<'a> { AuxExportKind::Setter { class, field: f.to_string(), + consumed: export.consumed, } } _ if op.is_static => AuxExportKind::StaticFunction { @@ -806,6 +808,7 @@ impl<'a> Context<'a> { kind: AuxExportKind::Getter { class: struct_.name.to_string(), field: field.name.to_string(), + consumed: false, }, generate_typescript: field.generate_typescript, }, @@ -832,6 +835,7 @@ impl<'a> Context<'a> { kind: AuxExportKind::Setter { class: struct_.name.to_string(), field: field.name.to_string(), + consumed: false, }, generate_typescript: field.generate_typescript, }, diff --git a/crates/cli-support/src/wit/nonstandard.rs b/crates/cli-support/src/wit/nonstandard.rs index 1bebca63c28..0c0d94fa967 100644 --- a/crates/cli-support/src/wit/nonstandard.rs +++ b/crates/cli-support/src/wit/nonstandard.rs @@ -105,12 +105,22 @@ pub enum AuxExportKind { /// This function is intended to be a getter for a field on a class. The /// first argument is the internal pointer and the returned value is /// expected to be the field. - Getter { class: String, field: String }, + Getter { + class: String, + field: String, + // same as `consumed` in `Method` + consumed: bool, + }, /// This function is intended to be a setter for a field on a class. The /// first argument is the internal pointer and the second argument is /// expected to be the field's new value. - Setter { class: String, field: String }, + Setter { + class: String, + field: String, + // same as `consumed` in `Method` + consumed: bool, + }, /// This is a free function (ish) but scoped inside of a class name. StaticFunction { class: String, name: String }, diff --git a/crates/cli-support/src/wit/section.rs b/crates/cli-support/src/wit/section.rs index e2703c4713a..88d9892a3db 100644 --- a/crates/cli-support/src/wit/section.rs +++ b/crates/cli-support/src/wit/section.rs @@ -369,7 +369,7 @@ fn check_standard_export(export: &AuxExport) -> Result<(), Error> { name, ); } - AuxExportKind::Getter { class, field } => { + AuxExportKind::Getter { class, field, .. } => { bail!( "cannot export `{}::{}` getter function when generating \ a standalone WebAssembly module with no JS glue", @@ -377,7 +377,7 @@ fn check_standard_export(export: &AuxExport) -> Result<(), Error> { field, ); } - AuxExportKind::Setter { class, field } => { + AuxExportKind::Setter { class, field, .. } => { bail!( "cannot export `{}::{}` setter function when generating \ a standalone WebAssembly module with no JS glue", diff --git a/examples/add/src/lib.rs b/examples/add/src/lib.rs index ad4ffde34f4..c056a21c1e7 100644 --- a/examples/add/src/lib.rs +++ b/examples/add/src/lib.rs @@ -4,3 +4,21 @@ use wasm_bindgen::prelude::*; pub fn add(a: u32, b: u32) -> u32 { a + b } + +#[wasm_bindgen] +#[derive(Copy, Clone)] +pub struct Answer(u32); + +#[wasm_bindgen] +impl Answer { + pub fn new() -> Answer { + Answer(41) + } + #[wasm_bindgen(getter)] + pub fn the_answer(self) -> u32 { + self.0 + 1 + } + pub fn foo(self) -> u32 { + self.0 + 1 + } +} diff --git a/tests/wasm/validate_prt.js b/tests/wasm/validate_prt.js index ad13738593a..070d71dfa9f 100644 --- a/tests/wasm/validate_prt.js +++ b/tests/wasm/validate_prt.js @@ -33,4 +33,11 @@ exports.js_works = () => { useMoved(); moveMoved(); methodMoved(); + + const a = new wasm.Fruit('a'); + a.prop; + assertMovedPtrThrows(() => a.prop); + const b = new wasm.Fruit('a'); + b.prop = 3; + assertMovedPtrThrows(() => { b.prop = 4; }); }; diff --git a/tests/wasm/validate_prt.rs b/tests/wasm/validate_prt.rs index 328a1a0fa6f..84cbf1d957e 100644 --- a/tests/wasm/validate_prt.rs +++ b/tests/wasm/validate_prt.rs @@ -25,6 +25,14 @@ impl Fruit { pub fn rot(self) { drop(self); } + + #[wasm_bindgen(getter)] + pub fn prop(self) -> u32 { + 0 + } + + #[wasm_bindgen(setter)] + pub fn set_prop(self, _val: u32) {} } #[wasm_bindgen]