From 673a371a5d47de879d354bd230ae64cfbf2a215b Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Thu, 21 Sep 2023 19:53:05 +1000 Subject: [PATCH 1/6] Implement `Into` for `Vec` This means that `Vec`s can now be returned from `async` functions. Fixes #3155. I had to add a new `VectorIntoJsValue` trait, since similarly to `VectorIntoWasmAbi` the orphan rule won't let us directly implement `From>` for `JsValue` outside of `wasm-bindgen`. --- crates/backend/src/codegen.rs | 12 ++++ crates/cli-support/src/intrinsic.rs | 39 ++++++++++ crates/cli-support/src/js/mod.rs | 25 +++++++ src/lib.rs | 106 ++++++++++++++++++++++++++++ tests/wasm/async_vecs.js | 11 +++ tests/wasm/async_vecs.rs | 66 +++++++++++++++++ tests/wasm/main.rs | 1 + 7 files changed, 260 insertions(+) create mode 100644 tests/wasm/async_vecs.js create mode 100644 tests/wasm/async_vecs.rs diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index bbcbc9cea14..65c8cd08915 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -365,6 +365,12 @@ impl ToTokens for ast::Struct { #wasm_bindgen::convert::js_value_vector_from_abi(js) } } + + impl #wasm_bindgen::__rt::VectorIntoJsValue for #name { + fn vector_into_jsvalue(vector: #wasm_bindgen::__rt::std::boxed::Box<[#name]>) -> #wasm_bindgen::JsValue { + #wasm_bindgen::__rt::js_value_vector_into_jsvalue(vector) + } + } }) .to_tokens(tokens); @@ -1509,6 +1515,12 @@ impl ToTokens for ast::Enum { #wasm_bindgen::convert::js_value_vector_from_abi(js) } } + + impl #wasm_bindgen::__rt::VectorIntoJsValue for #enum_name { + fn vector_into_jsvalue(vector: #wasm_bindgen::__rt::std::boxed::Box<[#enum_name]>) -> #wasm_bindgen::JsValue { + #wasm_bindgen::__rt::js_value_vector_into_jsvalue(vector) + } + } }) .to_tokens(into); } diff --git a/crates/cli-support/src/intrinsic.rs b/crates/cli-support/src/intrinsic.rs index ea209a47fa4..44a5079f4ed 100644 --- a/crates/cli-support/src/intrinsic.rs +++ b/crates/cli-support/src/intrinsic.rs @@ -264,6 +264,45 @@ intrinsics! { #[symbol = "__wbindgen_copy_to_typed_array"] #[signature = fn(slice(U8), ref_externref()) -> Unit] CopyToTypedArray, + #[symbol = "__wbindgen_uint8_array_new"] + #[signature = fn(slice(U8)) -> Externref] + Uint8ArrayNew, + #[symbol = "__wbindgen_uint8_clamped_array_new"] + #[signature = fn(slice(ClampedU8)) -> Externref] + Uint8ClampedArrayNew, + #[symbol = "__wbindgen_uint16_array_new"] + #[signature = fn(slice(U16)) -> Externref] + Uint16ArrayNew, + #[symbol = "__wbindgen_uint32_array_new"] + #[signature = fn(slice(U32)) -> Externref] + Uint32ArrayNew, + #[symbol = "__wbindgen_biguint64_array_new"] + #[signature = fn(slice(U64)) -> Externref] + BigUint64ArrayNew, + #[symbol = "__wbindgen_int8_array_new"] + #[signature = fn(slice(I8)) -> Externref] + Int8ArrayNew, + #[symbol = "__wbindgen_int16_array_new"] + #[signature = fn(slice(I16)) -> Externref] + Int16ArrayNew, + #[symbol = "__wbindgen_int32_array_new"] + #[signature = fn(slice(I32)) -> Externref] + Int32ArrayNew, + #[symbol = "__wbindgen_bigint64_array_new"] + #[signature = fn(slice(I64)) -> Externref] + BigInt64ArrayNew, + #[symbol = "__wbindgen_float32_array_new"] + #[signature = fn(slice(F32)) -> Externref] + Float32ArrayNew, + #[symbol = "__wbindgen_float64_array_new"] + #[signature = fn(slice(F64)) -> Externref] + Float64ArrayNew, + #[symbol = "__wbindgen_array_new"] + #[signature = fn() -> Externref] + ArrayNew, + #[symbol = "__wbindgen_array_push"] + #[signature = fn(ref_externref(), Externref) -> Unit] + ArrayPush, #[symbol = "__wbindgen_externref_heap_live_count"] #[signature = fn() -> I32] ExternrefHeapLiveCount, diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 738035e69f8..39c33c7803c 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -3577,6 +3577,31 @@ impl<'a> Context<'a> { ) } + Intrinsic::Uint8ArrayNew + | Intrinsic::Uint8ClampedArrayNew + | Intrinsic::Uint16ArrayNew + | Intrinsic::Uint32ArrayNew + | Intrinsic::BigUint64ArrayNew + | Intrinsic::Int8ArrayNew + | Intrinsic::Int16ArrayNew + | Intrinsic::Int32ArrayNew + | Intrinsic::BigInt64ArrayNew + | Intrinsic::Float32ArrayNew + | Intrinsic::Float64ArrayNew => { + assert_eq!(args.len(), 1); + args[0].clone() + } + + Intrinsic::ArrayNew => { + assert_eq!(args.len(), 0); + "[]".to_string() + } + + Intrinsic::ArrayPush => { + assert_eq!(args.len(), 2); + format!("{}.push({})", args[0], args[1]) + } + Intrinsic::ExternrefHeapLiveCount => { assert_eq!(args.len(), 0); self.expose_global_heap(); diff --git a/src/lib.rs b/src/lib.rs index fdef0e8d39a..cc1d3110dc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1098,6 +1098,21 @@ externs! { fn __wbindgen_copy_to_typed_array(ptr: *const u8, len: usize, idx: u32) -> (); + fn __wbindgen_uint8_array_new(ptr: *mut u8, len: usize) -> u32; + fn __wbindgen_uint8_clamped_array_new(ptr: *mut u8, len: usize) -> u32; + fn __wbindgen_uint16_array_new(ptr: *mut u16, len: usize) -> u32; + fn __wbindgen_uint32_array_new(ptr: *mut u32, len: usize) -> u32; + fn __wbindgen_biguint64_array_new(ptr: *mut u64, len: usize) -> u32; + fn __wbindgen_int8_array_new(ptr: *mut i8, len: usize) -> u32; + fn __wbindgen_int16_array_new(ptr: *mut i16, len: usize) -> u32; + fn __wbindgen_int32_array_new(ptr: *mut i32, len: usize) -> u32; + fn __wbindgen_bigint64_array_new(ptr: *mut i64, len: usize) -> u32; + fn __wbindgen_float32_array_new(ptr: *mut f32, len: usize) -> u32; + fn __wbindgen_float64_array_new(ptr: *mut f64, len: usize) -> u32; + + fn __wbindgen_array_new() -> u32; + fn __wbindgen_array_push(array: u32, value: u32) -> (); + fn __wbindgen_not(idx: u32) -> u32; fn __wbindgen_exports() -> u32; @@ -1804,6 +1819,35 @@ pub mod __rt { } } } + + if_std! { + use core::mem; + use std::boxed::Box; + + /// Trait for element types to implement `Into` for vectors of + /// themselves, which isn't possible directly thanks to the orphan rule. + pub trait VectorIntoJsValue: Sized { + fn vector_into_jsvalue(vector: Box<[Self]>) -> JsValue; + } + + impl From> for JsValue { + fn from(vector: Box<[T]>) -> Self { + T::vector_into_jsvalue(vector) + } + } + + pub fn js_value_vector_into_jsvalue>(vector: Box<[T]>) -> JsValue { + let result = unsafe { JsValue::_new(super::__wbindgen_array_new()) }; + for value in vector.into_vec() { + let js: JsValue = value.into(); + unsafe { super::__wbindgen_array_push(result.idx, js.idx) } + // `__wbindgen_array_push` takes ownership over `js` and has already dropped it, + // so don't drop it again. + mem::forget(js); + } + result + } + } } /// A wrapper type around slices and vectors for binding the `Uint8ClampedArray` @@ -1922,3 +1966,65 @@ impl From for JsValue { error.value } } + +macro_rules! typed_arrays { + ($($ty:ident $ctor:ident $clamped_ctor:ident,)*) => { + $( + impl From> for JsValue { + fn from(mut vec: Vec<$ty>) -> Self { + let result = unsafe { JsValue::_new($ctor(vec.as_mut_ptr(), vec.len())) }; + mem::forget(vec); + result + } + } + + impl From>> for JsValue { + fn from(mut vec: Clamped>) -> Self { + let result = unsafe { JsValue::_new($clamped_ctor(vec.as_mut_ptr(), vec.len())) }; + mem::forget(vec); + result + } + } + )* + }; +} + +typed_arrays! { + u8 __wbindgen_uint8_array_new __wbindgen_uint8_clamped_array_new, + u16 __wbindgen_uint16_array_new __wbindgen_uint16_array_new, + u32 __wbindgen_uint32_array_new __wbindgen_uint32_array_new, + u64 __wbindgen_biguint64_array_new __wbindgen_biguint64_array_new, + i8 __wbindgen_int8_array_new __wbindgen_int8_array_new, + i16 __wbindgen_int16_array_new __wbindgen_int16_array_new, + i32 __wbindgen_int32_array_new __wbindgen_int32_array_new, + i64 __wbindgen_bigint64_array_new __wbindgen_bigint64_array_new, + f32 __wbindgen_float32_array_new __wbindgen_float32_array_new, + f64 __wbindgen_float64_array_new __wbindgen_float64_array_new, +} + +impl __rt::VectorIntoJsValue for JsValue { + fn vector_into_jsvalue(vector: Box<[JsValue]>) -> JsValue { + __rt::js_value_vector_into_jsvalue::(vector) + } +} + +impl __rt::VectorIntoJsValue for T { + fn vector_into_jsvalue(vector: Box<[T]>) -> JsValue { + __rt::js_value_vector_into_jsvalue::(vector) + } +} + +impl __rt::VectorIntoJsValue for String { + fn vector_into_jsvalue(vector: Box<[String]>) -> JsValue { + __rt::js_value_vector_into_jsvalue::(vector) + } +} + +impl From> for JsValue +where + JsValue: From>, +{ + fn from(vector: Vec) -> Self { + JsValue::from(vector.into_boxed_slice()) + } +} diff --git a/tests/wasm/async_vecs.js b/tests/wasm/async_vecs.js new file mode 100644 index 00000000000..5e10a24edc0 --- /dev/null +++ b/tests/wasm/async_vecs.js @@ -0,0 +1,11 @@ +const wasm = require('wasm-bindgen-test.js'); +const assert = require('assert'); + +exports.js_works = async () => { + assert.deepStrictEqual(await wasm.async_number_vec(), new Int32Array([1, -3, 7, 12])); + assert.deepStrictEqual(await wasm.async_jsvalue_vec(), [1, "hi", new Float64Array(), null]); + assert.deepStrictEqual(await wasm.async_import_vec(), [/hi|bye/, /hello w[a-z]rld/]); + assert.deepStrictEqual(await wasm.async_string_vec(), ["a", "b", "c"]); + assert.strictEqual((await wasm.async_struct_vec()).length, 2); + assert.deepStrictEqual(await wasm.async_enum_vec(), [wasm.AnotherEnum.C, wasm.AnotherEnum.A, wasm.AnotherEnum.B]); +}; diff --git a/tests/wasm/async_vecs.rs b/tests/wasm/async_vecs.rs new file mode 100644 index 00000000000..d1705eb1695 --- /dev/null +++ b/tests/wasm/async_vecs.rs @@ -0,0 +1,66 @@ +use wasm_bindgen::prelude::*; +use wasm_bindgen_test::*; + +#[wasm_bindgen(module = "tests/wasm/async_vecs.js")] +extern "C" { + async fn js_works(); +} + +#[wasm_bindgen] +extern "C" { + pub type RegExp; + #[wasm_bindgen(constructor)] + fn new(re: &str) -> RegExp; +} + +#[wasm_bindgen] +pub async fn async_number_vec() -> Vec { + vec![1, -3, 7, 12] +} + +#[wasm_bindgen] +pub async fn async_jsvalue_vec() -> Vec { + vec![ + 1u32.into(), + "hi".into(), + Vec::::new().into(), + JsValue::NULL, + ] +} + +#[wasm_bindgen] +pub async fn async_import_vec() -> Vec { + vec![RegExp::new("hi|bye"), RegExp::new("hello w[a-z]rld")] +} + +#[wasm_bindgen] +pub async fn async_string_vec() -> Vec { + vec!["a".to_owned(), "b".to_owned(), "c".to_owned()] +} + +#[wasm_bindgen] +#[derive(Clone)] +pub struct AnotherStruct; + +#[wasm_bindgen] +pub async fn async_struct_vec() -> Vec { + vec![AnotherStruct; 2] +} + +#[wasm_bindgen] +#[derive(Clone)] +pub enum AnotherEnum { + A, + B, + C, +} + +#[wasm_bindgen] +pub async fn async_enum_vec() -> Vec { + vec![AnotherEnum::C, AnotherEnum::A, AnotherEnum::B] +} + +#[wasm_bindgen_test] +async fn works() { + js_works().await; +} diff --git a/tests/wasm/main.rs b/tests/wasm/main.rs index 72bb5c414f4..00e58de56a6 100644 --- a/tests/wasm/main.rs +++ b/tests/wasm/main.rs @@ -16,6 +16,7 @@ use wasm_bindgen::prelude::*; pub mod api; pub mod arg_names; +pub mod async_vecs; pub mod bigint; pub mod char; pub mod classes; From 3610a1701718b3bd1310f59f754b55d2508b23cd Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Thu, 21 Sep 2023 20:34:31 +1000 Subject: [PATCH 2/6] Implement Into for boxed slices of numbers as well --- src/lib.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cc1d3110dc1..d8e88b0205b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1970,18 +1970,18 @@ impl From for JsValue { macro_rules! typed_arrays { ($($ty:ident $ctor:ident $clamped_ctor:ident,)*) => { $( - impl From> for JsValue { - fn from(mut vec: Vec<$ty>) -> Self { - let result = unsafe { JsValue::_new($ctor(vec.as_mut_ptr(), vec.len())) }; - mem::forget(vec); + impl From> for JsValue { + fn from(mut vector: Box<[$ty]>) -> Self { + let result = unsafe { JsValue::_new($ctor(vector.as_mut_ptr(), vector.len())) }; + mem::forget(vector); result } } - impl From>> for JsValue { - fn from(mut vec: Clamped>) -> Self { - let result = unsafe { JsValue::_new($clamped_ctor(vec.as_mut_ptr(), vec.len())) }; - mem::forget(vec); + impl From>> for JsValue { + fn from(mut vector: Clamped>) -> Self { + let result = unsafe { JsValue::_new($clamped_ctor(vector.as_mut_ptr(), vector.len())) }; + mem::forget(vector); result } } @@ -2028,3 +2028,12 @@ where JsValue::from(vector.into_boxed_slice()) } } + +impl From>> for JsValue +where + JsValue: From>>, +{ + fn from(vector: Clamped>) -> Self { + JsValue::from(Clamped(vector.0.into_boxed_slice())) + } +} From 4bcf0379f459339c6e9a3f7135012b5377c36377 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Tue, 6 Feb 2024 11:08:41 +1100 Subject: [PATCH 3/6] Add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 141143e0b6e..d62a190e8c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,9 @@ Released 2024-02-06 * Add bindings for `USBDevice.forget()`. [#3821](https://github.com/rustwasm/wasm-bindgen/pull/3821) +* Added support for returning `Vec`s from async functions. + [#3630](https://github.com/rustwasm/wasm-bindgen/pull/3630) + ### Changed * Stabilize `ClipboardEvent`. From ab75f753e9b51089a922f96a8a0e82d24673c20c Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Mon, 25 Mar 2024 10:31:01 +1100 Subject: [PATCH 4/6] Fix memory leak --- crates/cli-support/src/intrinsic.rs | 26 +++++++++++++++----------- tests/wasm/async_vecs.js | 8 +++++++- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/crates/cli-support/src/intrinsic.rs b/crates/cli-support/src/intrinsic.rs index 44a5079f4ed..6141fdb4a52 100644 --- a/crates/cli-support/src/intrinsic.rs +++ b/crates/cli-support/src/intrinsic.rs @@ -79,6 +79,10 @@ fn slice(contents: Descriptor) -> Descriptor { Descriptor::Ref(Box::new(Descriptor::Slice(Box::new(contents)))) } +fn vector(contents: Descriptor) -> Descriptor { + Descriptor::Vector(Box::new(contents)) +} + intrinsics! { pub enum Intrinsic { #[symbol = "__wbindgen_jsval_eq"] @@ -265,37 +269,37 @@ intrinsics! { #[signature = fn(slice(U8), ref_externref()) -> Unit] CopyToTypedArray, #[symbol = "__wbindgen_uint8_array_new"] - #[signature = fn(slice(U8)) -> Externref] + #[signature = fn(vector(U8)) -> Externref] Uint8ArrayNew, #[symbol = "__wbindgen_uint8_clamped_array_new"] - #[signature = fn(slice(ClampedU8)) -> Externref] + #[signature = fn(vector(ClampedU8)) -> Externref] Uint8ClampedArrayNew, #[symbol = "__wbindgen_uint16_array_new"] - #[signature = fn(slice(U16)) -> Externref] + #[signature = fn(vector(U16)) -> Externref] Uint16ArrayNew, #[symbol = "__wbindgen_uint32_array_new"] - #[signature = fn(slice(U32)) -> Externref] + #[signature = fn(vector(U32)) -> Externref] Uint32ArrayNew, #[symbol = "__wbindgen_biguint64_array_new"] - #[signature = fn(slice(U64)) -> Externref] + #[signature = fn(vector(U64)) -> Externref] BigUint64ArrayNew, #[symbol = "__wbindgen_int8_array_new"] - #[signature = fn(slice(I8)) -> Externref] + #[signature = fn(vector(I8)) -> Externref] Int8ArrayNew, #[symbol = "__wbindgen_int16_array_new"] - #[signature = fn(slice(I16)) -> Externref] + #[signature = fn(vector(I16)) -> Externref] Int16ArrayNew, #[symbol = "__wbindgen_int32_array_new"] - #[signature = fn(slice(I32)) -> Externref] + #[signature = fn(vector(I32)) -> Externref] Int32ArrayNew, #[symbol = "__wbindgen_bigint64_array_new"] - #[signature = fn(slice(I64)) -> Externref] + #[signature = fn(vector(I64)) -> Externref] BigInt64ArrayNew, #[symbol = "__wbindgen_float32_array_new"] - #[signature = fn(slice(F32)) -> Externref] + #[signature = fn(vector(F32)) -> Externref] Float32ArrayNew, #[symbol = "__wbindgen_float64_array_new"] - #[signature = fn(slice(F64)) -> Externref] + #[signature = fn(vector(F64)) -> Externref] Float64ArrayNew, #[symbol = "__wbindgen_array_new"] #[signature = fn() -> Externref] diff --git a/tests/wasm/async_vecs.js b/tests/wasm/async_vecs.js index 5e10a24edc0..5ff6550802c 100644 --- a/tests/wasm/async_vecs.js +++ b/tests/wasm/async_vecs.js @@ -2,10 +2,16 @@ const wasm = require('wasm-bindgen-test.js'); const assert = require('assert'); exports.js_works = async () => { - assert.deepStrictEqual(await wasm.async_number_vec(), new Int32Array([1, -3, 7, 12])); assert.deepStrictEqual(await wasm.async_jsvalue_vec(), [1, "hi", new Float64Array(), null]); assert.deepStrictEqual(await wasm.async_import_vec(), [/hi|bye/, /hello w[a-z]rld/]); assert.deepStrictEqual(await wasm.async_string_vec(), ["a", "b", "c"]); assert.strictEqual((await wasm.async_struct_vec()).length, 2); assert.deepStrictEqual(await wasm.async_enum_vec(), [wasm.AnotherEnum.C, wasm.AnotherEnum.A, wasm.AnotherEnum.B]); + + const numberVec = await wasm.async_number_vec(); + assert.deepStrictEqual(numberVec, new Int32Array([1, -3, 7, 12])); + // Make sure `numberVec` is a fresh `Int32Array`, not a view into Wasm memory, + // so that it can be GC'd without the whole Wasm module having to be GC'd as + // well. + assert.strictEqual(numberVec.byteLength, numberVec.buffer.byteLength); }; From 215ccc85d294fb64f7b06a267a574600aa03da76 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Mon, 25 Mar 2024 10:55:27 +1100 Subject: [PATCH 5/6] Add missing if_std! --- src/lib.rs | 78 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d8e88b0205b..accc371075c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1989,51 +1989,53 @@ macro_rules! typed_arrays { }; } -typed_arrays! { - u8 __wbindgen_uint8_array_new __wbindgen_uint8_clamped_array_new, - u16 __wbindgen_uint16_array_new __wbindgen_uint16_array_new, - u32 __wbindgen_uint32_array_new __wbindgen_uint32_array_new, - u64 __wbindgen_biguint64_array_new __wbindgen_biguint64_array_new, - i8 __wbindgen_int8_array_new __wbindgen_int8_array_new, - i16 __wbindgen_int16_array_new __wbindgen_int16_array_new, - i32 __wbindgen_int32_array_new __wbindgen_int32_array_new, - i64 __wbindgen_bigint64_array_new __wbindgen_bigint64_array_new, - f32 __wbindgen_float32_array_new __wbindgen_float32_array_new, - f64 __wbindgen_float64_array_new __wbindgen_float64_array_new, -} - -impl __rt::VectorIntoJsValue for JsValue { - fn vector_into_jsvalue(vector: Box<[JsValue]>) -> JsValue { - __rt::js_value_vector_into_jsvalue::(vector) +if_std! { + typed_arrays! { + u8 __wbindgen_uint8_array_new __wbindgen_uint8_clamped_array_new, + u16 __wbindgen_uint16_array_new __wbindgen_uint16_array_new, + u32 __wbindgen_uint32_array_new __wbindgen_uint32_array_new, + u64 __wbindgen_biguint64_array_new __wbindgen_biguint64_array_new, + i8 __wbindgen_int8_array_new __wbindgen_int8_array_new, + i16 __wbindgen_int16_array_new __wbindgen_int16_array_new, + i32 __wbindgen_int32_array_new __wbindgen_int32_array_new, + i64 __wbindgen_bigint64_array_new __wbindgen_bigint64_array_new, + f32 __wbindgen_float32_array_new __wbindgen_float32_array_new, + f64 __wbindgen_float64_array_new __wbindgen_float64_array_new, + } + + impl __rt::VectorIntoJsValue for JsValue { + fn vector_into_jsvalue(vector: Box<[JsValue]>) -> JsValue { + __rt::js_value_vector_into_jsvalue::(vector) + } } -} -impl __rt::VectorIntoJsValue for T { - fn vector_into_jsvalue(vector: Box<[T]>) -> JsValue { - __rt::js_value_vector_into_jsvalue::(vector) + impl __rt::VectorIntoJsValue for T { + fn vector_into_jsvalue(vector: Box<[T]>) -> JsValue { + __rt::js_value_vector_into_jsvalue::(vector) + } } -} -impl __rt::VectorIntoJsValue for String { - fn vector_into_jsvalue(vector: Box<[String]>) -> JsValue { - __rt::js_value_vector_into_jsvalue::(vector) + impl __rt::VectorIntoJsValue for String { + fn vector_into_jsvalue(vector: Box<[String]>) -> JsValue { + __rt::js_value_vector_into_jsvalue::(vector) + } } -} -impl From> for JsValue -where - JsValue: From>, -{ - fn from(vector: Vec) -> Self { - JsValue::from(vector.into_boxed_slice()) + impl From> for JsValue + where + JsValue: From>, + { + fn from(vector: Vec) -> Self { + JsValue::from(vector.into_boxed_slice()) + } } -} -impl From>> for JsValue -where - JsValue: From>>, -{ - fn from(vector: Clamped>) -> Self { - JsValue::from(Clamped(vector.0.into_boxed_slice())) + impl From>> for JsValue + where + JsValue: From>>, + { + fn from(vector: Clamped>) -> Self { + JsValue::from(Clamped(vector.0.into_boxed_slice())) + } } } From 0bbfe2d0b9aad8469c61229d12277bda04e4f117 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Mon, 25 Mar 2024 11:09:05 +1100 Subject: [PATCH 6/6] Move the changelog entry to the right spot --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d62a190e8c2..0add0955534 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ * Add method `copy_within` for TypedArray, add methods `find_last`,`find_last_index` for Array. [#3888](https://github.com/rustwasm/wasm-bindgen/pull/3888) +* Added support for returning `Vec`s from async functions. + [#3630](https://github.com/rustwasm/wasm-bindgen/pull/3630) + ### Changed * Stabilize Web Share API. @@ -82,9 +85,6 @@ Released 2024-02-06 * Add bindings for `USBDevice.forget()`. [#3821](https://github.com/rustwasm/wasm-bindgen/pull/3821) -* Added support for returning `Vec`s from async functions. - [#3630](https://github.com/rustwasm/wasm-bindgen/pull/3630) - ### Changed * Stabilize `ClipboardEvent`.