add dyn for Fn (#2212)

* add dyn for Fn

* revert invalid-imports changes

* add one more dyn in doc comments
This commit is contained in:
Cameron Taggart 2020-06-23 09:24:26 -06:00 committed by GitHub
parent 810e6a84c8
commit 1a7d6de1b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 87 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ yarn.lock
/publish /publish
/publish.exe /publish.exe
.vscode .vscode
webdriver.json

View File

@ -40,7 +40,7 @@ In addition to the shims we talked about above which JS generates the macro
``` ```
#[no_mangle] #[no_mangle]
pub extern "C" fn __wbindgen_describe_greet() { pub extern "C" fn __wbindgen_describe_greet() {
<Fn(&str)>::describe(); <dyn Fn(&str)>::describe();
} }
``` ```

View File

@ -86,7 +86,7 @@ functions imported into Rust.
Mentioned above not all Rust types will fit within 32 bits. While we can Mentioned above not all Rust types will fit within 32 bits. While we can
communicate an `f64` we don't necessarily have the ability to use all the bits. communicate an `f64` we don't necessarily have the ability to use all the bits.
Types like `&str` need to communicate two items, a pointer and a length (64 Types like `&str` need to communicate two items, a pointer and a length (64
bits). Other types like `&Closure<Fn()>` have even more information to bits). Other types like `&Closure<dyn Fn()>` have even more information to
transmit. transmit.
As a result we need a method of communicating more data through the signatures As a result we need a method of communicating more data through the signatures

View File

@ -11,17 +11,17 @@ JavaScript in two variants:
## Stack-Lifetime Closures ## Stack-Lifetime Closures
Closures with a stack lifetime are passed to JavaScript as either `&Fn` or `&mut Closures with a stack lifetime are passed to JavaScript as either `&dyn Fn` or `&mut
FnMut` trait objects: dyn FnMut` trait objects:
```rust ```rust
// Import JS functions that take closures // Import JS functions that take closures
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
fn takes_immutable_closure(f: &Fn()); fn takes_immutable_closure(f: &dyn Fn());
fn takes_mutable_closure(f: &mut FnMut()); fn takes_mutable_closure(f: &mut dyn FnMut());
} }
// Usage // Usage
@ -45,7 +45,7 @@ Closures also support arguments and return values like exports do, for example:
```rust ```rust
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
fn takes_closure_that_takes_int_and_returns_string(x: &Fn(u32) -> String); fn takes_closure_that_takes_int_and_returns_string(x: &dyn Fn(u32) -> String);
} }
takes_closure_that_takes_int_and_returns_string(&|x: u32| -> String { takes_closure_that_takes_int_and_returns_string(&|x: u32| -> String {
@ -81,7 +81,7 @@ as arguments and returns.
```rust ```rust
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
fn setInterval(closure: &Closure<FnMut()>, millis: u32) -> f64; fn setInterval(closure: &Closure<dyn FnMut()>, millis: u32) -> f64;
fn cancelInterval(token: f64); fn cancelInterval(token: f64);
#[wasm_bindgen(js_namespace = console)] #[wasm_bindgen(js_namespace = console)]
@ -90,7 +90,7 @@ extern "C" {
#[wasm_bindgen] #[wasm_bindgen]
pub struct Interval { pub struct Interval {
closure: Closure<FnMut()>, closure: Closure<dyn FnMut()>,
token: f64, token: f64,
} }

View File

@ -16,7 +16,7 @@ all Web APIs)][webidl] have relatively straightforward translations into
* Callbacks are all represented as `js_sys::Function`. This means that all * Callbacks are all represented as `js_sys::Function`. This means that all
callbacks going through `web-sys` are a raw JS value. You can work with this callbacks going through `web-sys` are a raw JS value. You can work with this
by either juggling actual `js_sys::Function` instances or you can create a by either juggling actual `js_sys::Function` instances or you can create a
`Closure<FnMut(...)>`, extract the underlying `JsValue` with `as_ref`, and `Closure<dyn FnMut(...)>`, extract the underlying `JsValue` with `as_ref`, and
then use `JsCast::unchecked_ref` to convert it to a `js_sys::Function`. then use `JsCast::unchecked_ref` to convert it to a `js_sys::Function`.
[webidl]: https://heycam.github.io/webidl/ [webidl]: https://heycam.github.io/webidl/

View File

@ -48,7 +48,7 @@ use crate::UnwrapThrowExt;
/// ///
/// #[wasm_bindgen] /// #[wasm_bindgen]
/// extern "C" { /// extern "C" {
/// fn setInterval(closure: &Closure<FnMut()>, time: u32) -> i32; /// fn setInterval(closure: &Closure<dyn FnMut()>, time: u32) -> i32;
/// fn clearInterval(id: i32); /// fn clearInterval(id: i32);
/// ///
/// #[wasm_bindgen(js_namespace = console)] /// #[wasm_bindgen(js_namespace = console)]
@ -58,7 +58,7 @@ use crate::UnwrapThrowExt;
/// #[wasm_bindgen] /// #[wasm_bindgen]
/// pub struct IntervalHandle { /// pub struct IntervalHandle {
/// interval_id: i32, /// interval_id: i32,
/// _closure: Closure<FnMut()>, /// _closure: Closure<dyn FnMut()>,
/// } /// }
/// ///
/// impl Drop for IntervalHandle { /// impl Drop for IntervalHandle {
@ -73,7 +73,7 @@ use crate::UnwrapThrowExt;
/// // a JS closure. /// // a JS closure.
/// let cb = Closure::wrap(Box::new(|| { /// let cb = Closure::wrap(Box::new(|| {
/// log("interval elapsed!"); /// log("interval elapsed!");
/// }) as Box<FnMut()>); /// }) as Box<dyn FnMut()>);
/// ///
/// // Next we pass this via reference to the `setInterval` function, and /// // Next we pass this via reference to the `setInterval` function, and
/// // `setInterval` gets a handle to the corresponding JS closure. /// // `setInterval` gets a handle to the corresponding JS closure.
@ -101,7 +101,7 @@ use crate::UnwrapThrowExt;
/// #[wasm_bindgen] /// #[wasm_bindgen]
/// pub struct IntervalHandle { /// pub struct IntervalHandle {
/// interval_id: i32, /// interval_id: i32,
/// _closure: Closure<FnMut()>, /// _closure: Closure<dyn FnMut()>,
/// } /// }
/// ///
/// impl Drop for IntervalHandle { /// impl Drop for IntervalHandle {
@ -115,7 +115,7 @@ use crate::UnwrapThrowExt;
/// pub fn run() -> Result<IntervalHandle, JsValue> { /// pub fn run() -> Result<IntervalHandle, JsValue> {
/// let cb = Closure::wrap(Box::new(|| { /// let cb = Closure::wrap(Box::new(|| {
/// web_sys::console::log_1(&"inverval elapsed!".into()); /// web_sys::console::log_1(&"inverval elapsed!".into());
/// }) as Box<FnMut()>); /// }) as Box<dyn FnMut()>);
/// ///
/// let window = web_sys::window().unwrap(); /// let window = web_sys::window().unwrap();
/// let interval_id = window.set_interval_with_callback_and_timeout_and_arguments_0( /// let interval_id = window.set_interval_with_callback_and_timeout_and_arguments_0(
@ -144,7 +144,7 @@ use crate::UnwrapThrowExt;
/// ///
/// #[wasm_bindgen] /// #[wasm_bindgen]
/// extern "C" { /// extern "C" {
/// fn requestAnimationFrame(closure: &Closure<FnMut()>) -> u32; /// fn requestAnimationFrame(closure: &Closure<dyn FnMut()>) -> u32;
/// fn cancelAnimationFrame(id: u32); /// fn cancelAnimationFrame(id: u32);
/// ///
/// #[wasm_bindgen(js_namespace = console)] /// #[wasm_bindgen(js_namespace = console)]
@ -154,7 +154,7 @@ use crate::UnwrapThrowExt;
/// #[wasm_bindgen] /// #[wasm_bindgen]
/// pub struct AnimationFrameHandle { /// pub struct AnimationFrameHandle {
/// animation_id: u32, /// animation_id: u32,
/// _closure: Closure<FnMut()>, /// _closure: Closure<dyn FnMut()>,
/// } /// }
/// ///
/// impl Drop for AnimationFrameHandle { /// impl Drop for AnimationFrameHandle {
@ -377,12 +377,12 @@ where
// NB: we use a specific `T` for this `Closure<T>` impl block to avoid every // NB: we use a specific `T` for this `Closure<T>` impl block to avoid every
// call site having to provide an explicit, turbo-fished type like // call site having to provide an explicit, turbo-fished type like
// `Closure::<FnOnce()>::once(...)`. // `Closure::<dyn FnOnce()>::once(...)`.
impl Closure<dyn FnOnce()> { impl Closure<dyn FnOnce()> {
/// Create a `Closure` from a function that can only be called once. /// Create a `Closure` from a function that can only be called once.
/// ///
/// Since we have no way of enforcing that JS cannot attempt to call this /// Since we have no way of enforcing that JS cannot attempt to call this
/// `FnOne(A...) -> R` more than once, this produces a `Closure<FnMut(A...) /// `FnOne(A...) -> R` more than once, this produces a `Closure<dyn FnMut(A...)
/// -> R>` that will dynamically throw a JavaScript error if called more /// -> R>` that will dynamically throw a JavaScript error if called more
/// than once. /// than once.
/// ///
@ -404,7 +404,7 @@ impl Closure<dyn FnOnce()> {
/// ///
/// // Create a `Closure` from `f`. Note that the `Closure`'s type parameter /// // Create a `Closure` from `f`. Note that the `Closure`'s type parameter
/// // is `FnMut`, even though `f` is `FnOnce`. /// // is `FnMut`, even though `f` is `FnOnce`.
/// let closure: Closure<FnMut() -> String> = Closure::once(f); /// let closure: Closure<dyn FnMut() -> String> = Closure::once(f);
/// ``` /// ```
pub fn once<F, A, R>(fn_once: F) -> Closure<F::FnMut> pub fn once<F, A, R>(fn_once: F) -> Closure<F::FnMut>
where where

View File

@ -7,89 +7,89 @@ use wasm_bindgen_test::*;
#[wasm_bindgen(module = "tests/wasm/closures.js")] #[wasm_bindgen(module = "tests/wasm/closures.js")]
extern "C" { extern "C" {
fn works_call(a: &Fn()); fn works_call(a: &dyn Fn());
fn works_thread(a: &Fn(u32) -> u32) -> u32; fn works_thread(a: &dyn Fn(u32) -> u32) -> u32;
fn cannot_reuse_call(a: &Fn()); fn cannot_reuse_call(a: &dyn Fn());
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn cannot_reuse_call_again() -> Result<(), JsValue>; fn cannot_reuse_call_again() -> Result<(), JsValue>;
fn long_lived_call1(a: &Closure<Fn()>); fn long_lived_call1(a: &Closure<dyn Fn()>);
fn long_lived_call2(a: &Closure<FnMut(u32) -> u32>) -> u32; fn long_lived_call2(a: &Closure<dyn FnMut(u32) -> u32>) -> u32;
fn many_arity_call1(a: &Closure<Fn()>); fn many_arity_call1(a: &Closure<dyn Fn()>);
fn many_arity_call2(a: &Closure<Fn(u32)>); fn many_arity_call2(a: &Closure<dyn Fn(u32)>);
fn many_arity_call3(a: &Closure<Fn(u32, u32)>); fn many_arity_call3(a: &Closure<dyn Fn(u32, u32)>);
fn many_arity_call4(a: &Closure<Fn(u32, u32, u32)>); fn many_arity_call4(a: &Closure<dyn Fn(u32, u32, u32)>);
fn many_arity_call5(a: &Closure<Fn(u32, u32, u32, u32)>); fn many_arity_call5(a: &Closure<dyn Fn(u32, u32, u32, u32)>);
fn many_arity_call6(a: &Closure<Fn(u32, u32, u32, u32, u32)>); fn many_arity_call6(a: &Closure<dyn Fn(u32, u32, u32, u32, u32)>);
fn many_arity_call7(a: &Closure<Fn(u32, u32, u32, u32, u32, u32)>); fn many_arity_call7(a: &Closure<dyn Fn(u32, u32, u32, u32, u32, u32)>);
fn many_arity_call8(a: &Closure<Fn(u32, u32, u32, u32, u32, u32, u32)>); fn many_arity_call8(a: &Closure<dyn Fn(u32, u32, u32, u32, u32, u32, u32)>);
fn many_arity_call9(a: &Closure<Fn(u32, u32, u32, u32, u32, u32, u32, u32)>); fn many_arity_call9(a: &Closure<dyn Fn(u32, u32, u32, u32, u32, u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call1)] #[wasm_bindgen(js_name = many_arity_call1)]
fn many_arity_call_mut1(a: &Closure<FnMut()>); fn many_arity_call_mut1(a: &Closure<dyn FnMut()>);
#[wasm_bindgen(js_name = many_arity_call2)] #[wasm_bindgen(js_name = many_arity_call2)]
fn many_arity_call_mut2(a: &Closure<FnMut(u32)>); fn many_arity_call_mut2(a: &Closure<dyn FnMut(u32)>);
#[wasm_bindgen(js_name = many_arity_call3)] #[wasm_bindgen(js_name = many_arity_call3)]
fn many_arity_call_mut3(a: &Closure<FnMut(u32, u32)>); fn many_arity_call_mut3(a: &Closure<dyn FnMut(u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call4)] #[wasm_bindgen(js_name = many_arity_call4)]
fn many_arity_call_mut4(a: &Closure<FnMut(u32, u32, u32)>); fn many_arity_call_mut4(a: &Closure<dyn FnMut(u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call5)] #[wasm_bindgen(js_name = many_arity_call5)]
fn many_arity_call_mut5(a: &Closure<FnMut(u32, u32, u32, u32)>); fn many_arity_call_mut5(a: &Closure<dyn FnMut(u32, u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call6)] #[wasm_bindgen(js_name = many_arity_call6)]
fn many_arity_call_mut6(a: &Closure<FnMut(u32, u32, u32, u32, u32)>); fn many_arity_call_mut6(a: &Closure<dyn FnMut(u32, u32, u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call7)] #[wasm_bindgen(js_name = many_arity_call7)]
fn many_arity_call_mut7(a: &Closure<FnMut(u32, u32, u32, u32, u32, u32)>); fn many_arity_call_mut7(a: &Closure<dyn FnMut(u32, u32, u32, u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call8)] #[wasm_bindgen(js_name = many_arity_call8)]
fn many_arity_call_mut8(a: &Closure<FnMut(u32, u32, u32, u32, u32, u32, u32)>); fn many_arity_call_mut8(a: &Closure<dyn FnMut(u32, u32, u32, u32, u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call9)] #[wasm_bindgen(js_name = many_arity_call9)]
fn many_arity_call_mut9(a: &Closure<FnMut(u32, u32, u32, u32, u32, u32, u32, u32)>); fn many_arity_call_mut9(a: &Closure<dyn FnMut(u32, u32, u32, u32, u32, u32, u32, u32)>);
#[wasm_bindgen(js_name = many_arity_call1)] #[wasm_bindgen(js_name = many_arity_call1)]
fn many_arity_stack1(a: &Fn()); fn many_arity_stack1(a: &dyn Fn());
#[wasm_bindgen(js_name = many_arity_call2)] #[wasm_bindgen(js_name = many_arity_call2)]
fn many_arity_stack2(a: &Fn(u32)); fn many_arity_stack2(a: &dyn Fn(u32));
#[wasm_bindgen(js_name = many_arity_call3)] #[wasm_bindgen(js_name = many_arity_call3)]
fn many_arity_stack3(a: &Fn(u32, u32)); fn many_arity_stack3(a: &dyn Fn(u32, u32));
#[wasm_bindgen(js_name = many_arity_call4)] #[wasm_bindgen(js_name = many_arity_call4)]
fn many_arity_stack4(a: &Fn(u32, u32, u32)); fn many_arity_stack4(a: &dyn Fn(u32, u32, u32));
#[wasm_bindgen(js_name = many_arity_call5)] #[wasm_bindgen(js_name = many_arity_call5)]
fn many_arity_stack5(a: &Fn(u32, u32, u32, u32)); fn many_arity_stack5(a: &dyn Fn(u32, u32, u32, u32));
#[wasm_bindgen(js_name = many_arity_call6)] #[wasm_bindgen(js_name = many_arity_call6)]
fn many_arity_stack6(a: &Fn(u32, u32, u32, u32, u32)); fn many_arity_stack6(a: &dyn Fn(u32, u32, u32, u32, u32));
#[wasm_bindgen(js_name = many_arity_call7)] #[wasm_bindgen(js_name = many_arity_call7)]
fn many_arity_stack7(a: &Fn(u32, u32, u32, u32, u32, u32)); fn many_arity_stack7(a: &dyn Fn(u32, u32, u32, u32, u32, u32));
#[wasm_bindgen(js_name = many_arity_call8)] #[wasm_bindgen(js_name = many_arity_call8)]
fn many_arity_stack8(a: &Fn(u32, u32, u32, u32, u32, u32, u32)); fn many_arity_stack8(a: &dyn Fn(u32, u32, u32, u32, u32, u32, u32));
#[wasm_bindgen(js_name = many_arity_call9)] #[wasm_bindgen(js_name = many_arity_call9)]
fn many_arity_stack9(a: &Fn(u32, u32, u32, u32, u32, u32, u32, u32)); fn many_arity_stack9(a: &dyn Fn(u32, u32, u32, u32, u32, u32, u32, u32));
fn long_lived_dropping_cache(a: &Closure<Fn()>); fn long_lived_dropping_cache(a: &Closure<dyn Fn()>);
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn long_lived_dropping_call() -> Result<(), JsValue>; fn long_lived_dropping_call() -> Result<(), JsValue>;
fn long_fnmut_recursive_cache(a: &Closure<FnMut()>); fn long_fnmut_recursive_cache(a: &Closure<dyn FnMut()>);
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn long_fnmut_recursive_call() -> Result<(), JsValue>; fn long_fnmut_recursive_call() -> Result<(), JsValue>;
fn fnmut_call(a: &mut FnMut()); fn fnmut_call(a: &mut dyn FnMut());
fn fnmut_thread(a: &mut FnMut(u32) -> u32) -> u32; fn fnmut_thread(a: &mut dyn FnMut(u32) -> u32) -> u32;
fn fnmut_bad_call(a: &mut FnMut()); fn fnmut_bad_call(a: &mut dyn FnMut());
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn fnmut_bad_again(a: bool) -> Result<(), JsValue>; fn fnmut_bad_again(a: bool) -> Result<(), JsValue>;
fn string_arguments_call(a: &mut FnMut(String)); fn string_arguments_call(a: &mut dyn FnMut(String));
fn string_ret_call(a: &mut FnMut(String) -> String); fn string_ret_call(a: &mut dyn FnMut(String) -> String);
fn drop_during_call_save(a: &Closure<Fn()>); fn drop_during_call_save(a: &Closure<dyn Fn()>);
fn drop_during_call_call(); fn drop_during_call_call();
fn js_test_closure_returner(); fn js_test_closure_returner();
fn calling_it_throws(a: &Closure<FnMut()>) -> bool; fn calling_it_throws(a: &Closure<dyn FnMut()>) -> bool;
fn call_val(f: &JsValue); fn call_val(f: &JsValue);
@ -98,18 +98,18 @@ extern "C" {
fn pass_reference_first_arg_twice( fn pass_reference_first_arg_twice(
a: RefFirstArgument, a: RefFirstArgument,
b: &Closure<FnMut(&RefFirstArgument)>, b: &Closure<dyn FnMut(&RefFirstArgument)>,
c: &Closure<FnMut(&RefFirstArgument)>, c: &Closure<dyn FnMut(&RefFirstArgument)>,
); );
#[wasm_bindgen(js_name = pass_reference_first_arg_twice)] #[wasm_bindgen(js_name = pass_reference_first_arg_twice)]
fn pass_reference_first_arg_twice2( fn pass_reference_first_arg_twice2(
a: RefFirstArgument, a: RefFirstArgument,
b: &mut FnMut(&RefFirstArgument), b: &mut dyn FnMut(&RefFirstArgument),
c: &mut FnMut(&RefFirstArgument), c: &mut dyn FnMut(&RefFirstArgument),
); );
fn call_destroyed(a: &JsValue); fn call_destroyed(a: &JsValue);
fn js_store_forgotten_closure(closure: &Closure<Fn()>); fn js_store_forgotten_closure(closure: &Closure<dyn Fn()>);
fn js_call_forgotten_closure(); fn js_call_forgotten_closure();
} }
@ -130,7 +130,7 @@ fn cannot_reuse() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn debug() { fn debug() {
let closure = Closure::wrap(Box::new(|| {}) as Box<FnMut()>); let closure = Closure::wrap(Box::new(|| {}) as Box<dyn FnMut()>);
assert_eq!(&format!("{:?}", closure), "Closure { ... }"); assert_eq!(&format!("{:?}", closure), "Closure { ... }");
} }
@ -379,7 +379,7 @@ fn drop_drops() {
} }
} }
let a = A; let a = A;
let x: Closure<Fn()> = Closure::new(move || drop(&a)); let x: Closure<dyn Fn()> = Closure::new(move || drop(&a));
drop(x); drop(x);
unsafe { unsafe {
assert!(HIT); assert!(HIT);
@ -402,7 +402,7 @@ fn drop_during_call_ok() {
let rc2 = rc.clone(); let rc2 = rc.clone();
let x = 3; let x = 3;
let a = A; let a = A;
let x: Closure<Fn()> = Closure::new(move || { let x: Closure<dyn Fn()> = Closure::new(move || {
// "drop ourselves" // "drop ourselves"
drop(rc2.borrow_mut().take().unwrap()); drop(rc2.borrow_mut().take().unwrap());
@ -437,7 +437,7 @@ fn drop_during_call_ok() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn test_closure_returner() { fn test_closure_returner() {
type ClosureType = FnMut() -> BadStruct; type ClosureType = dyn FnMut() -> BadStruct;
use js_sys::{Object, Reflect}; use js_sys::{Object, Reflect};
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
@ -481,22 +481,22 @@ pub struct RefFirstArgument {
fn reference_as_first_argument_builds_at_all() { fn reference_as_first_argument_builds_at_all() {
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
fn ref_first_arg1(a: &Fn(&JsValue)); fn ref_first_arg1(a: &dyn Fn(&JsValue));
fn ref_first_arg2(a: &mut FnMut(&JsValue)); fn ref_first_arg2(a: &mut dyn FnMut(&JsValue));
fn ref_first_arg3(a: &Closure<Fn(&JsValue)>); fn ref_first_arg3(a: &Closure<dyn Fn(&JsValue)>);
fn ref_first_arg4(a: &Closure<FnMut(&JsValue)>); fn ref_first_arg4(a: &Closure<dyn FnMut(&JsValue)>);
fn ref_first_custom1(a: &Fn(&RefFirstArgument)); fn ref_first_custom1(a: &dyn Fn(&RefFirstArgument));
fn ref_first_custom2(a: &mut FnMut(&RefFirstArgument)); fn ref_first_custom2(a: &mut dyn FnMut(&RefFirstArgument));
fn ref_first_custom3(a: &Closure<Fn(&RefFirstArgument)>); fn ref_first_custom3(a: &Closure<dyn Fn(&RefFirstArgument)>);
fn ref_first_custom4(a: &Closure<FnMut(&RefFirstArgument)>); fn ref_first_custom4(a: &Closure<dyn FnMut(&RefFirstArgument)>);
} }
Closure::wrap(Box::new(|_: &JsValue| ()) as Box<Fn(&JsValue)>); Closure::wrap(Box::new(|_: &JsValue| ()) as Box<dyn Fn(&JsValue)>);
Closure::wrap(Box::new(|_: &JsValue| ()) as Box<FnMut(&JsValue)>); Closure::wrap(Box::new(|_: &JsValue| ()) as Box<dyn FnMut(&JsValue)>);
Closure::once(|_: &JsValue| ()); Closure::once(|_: &JsValue| ());
Closure::once_into_js(|_: &JsValue| ()); Closure::once_into_js(|_: &JsValue| ());
Closure::wrap(Box::new(|_: &RefFirstArgument| ()) as Box<Fn(&RefFirstArgument)>); Closure::wrap(Box::new(|_: &RefFirstArgument| ()) as Box<dyn Fn(&RefFirstArgument)>);
Closure::wrap(Box::new(|_: &RefFirstArgument| ()) as Box<FnMut(&RefFirstArgument)>); Closure::wrap(Box::new(|_: &RefFirstArgument| ()) as Box<dyn FnMut(&RefFirstArgument)>);
Closure::once(|_: &RefFirstArgument| ()); Closure::once(|_: &RefFirstArgument| ());
Closure::once_into_js(|_: &RefFirstArgument| ()); Closure::once_into_js(|_: &RefFirstArgument| ());
} }
@ -553,25 +553,25 @@ fn call_destroyed_doesnt_segfault() {
} }
let a = A(1, 1); let a = A(1, 1);
let a = Closure::wrap(Box::new(move || drop(&a)) as Box<Fn()>); let a = Closure::wrap(Box::new(move || drop(&a)) as Box<dyn Fn()>);
let b = a.as_ref().clone(); let b = a.as_ref().clone();
drop(a); drop(a);
call_destroyed(&b); call_destroyed(&b);
let a = A(2, 2); let a = A(2, 2);
let a = Closure::wrap(Box::new(move || drop(&a)) as Box<FnMut()>); let a = Closure::wrap(Box::new(move || drop(&a)) as Box<dyn FnMut()>);
let b = a.as_ref().clone(); let b = a.as_ref().clone();
drop(a); drop(a);
call_destroyed(&b); call_destroyed(&b);
let a = A(1, 1); let a = A(1, 1);
let a = Closure::wrap(Box::new(move |_: &JsValue| drop(&a)) as Box<Fn(&JsValue)>); let a = Closure::wrap(Box::new(move |_: &JsValue| drop(&a)) as Box<dyn Fn(&JsValue)>);
let b = a.as_ref().clone(); let b = a.as_ref().clone();
drop(a); drop(a);
call_destroyed(&b); call_destroyed(&b);
let a = A(2, 2); let a = A(2, 2);
let a = Closure::wrap(Box::new(move |_: &JsValue| drop(&a)) as Box<FnMut(&JsValue)>); let a = Closure::wrap(Box::new(move |_: &JsValue| drop(&a)) as Box<dyn FnMut(&JsValue)>);
let b = a.as_ref().clone(); let b = a.as_ref().clone();
drop(a); drop(a);
call_destroyed(&b); call_destroyed(&b);
@ -579,7 +579,7 @@ fn call_destroyed_doesnt_segfault() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn forget_works() { fn forget_works() {
let a = Closure::wrap(Box::new(|| {}) as Box<Fn()>); let a = Closure::wrap(Box::new(|| {}) as Box<dyn Fn()>);
js_store_forgotten_closure(&a); js_store_forgotten_closure(&a);
a.forget(); a.forget();
js_call_forgotten_closure(); js_call_forgotten_closure();