Skip to content

Commit

Permalink
add dyn for Fn (#2212)
Browse files Browse the repository at this point in the history
* add dyn for Fn

* revert invalid-imports changes

* add one more dyn in doc comments
  • Loading branch information
ctaggart authored Jun 23, 2020
1 parent 810e6a8 commit 1a7d6de
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 87 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ yarn.lock
/publish
/publish.exe
.vscode
webdriver.json
2 changes: 1 addition & 1 deletion guide/src/contributing/design/describe.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ In addition to the shims we talked about above which JS generates the macro
```
#[no_mangle]
pub extern "C" fn __wbindgen_describe_greet() {
<Fn(&str)>::describe();
<dyn Fn(&str)>::describe();
}
```

Expand Down
2 changes: 1 addition & 1 deletion guide/src/contributing/design/rust-type-conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ functions imported into Rust.
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.
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.

As a result we need a method of communicating more data through the signatures
Expand Down
14 changes: 7 additions & 7 deletions guide/src/reference/passing-rust-closures-to-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ JavaScript in two variants:

## Stack-Lifetime Closures

Closures with a stack lifetime are passed to JavaScript as either `&Fn` or `&mut
FnMut` trait objects:
Closures with a stack lifetime are passed to JavaScript as either `&dyn Fn` or `&mut
dyn FnMut` trait objects:

```rust
// Import JS functions that take closures

#[wasm_bindgen]
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
Expand All @@ -45,7 +45,7 @@ Closures also support arguments and return values like exports do, for example:
```rust
#[wasm_bindgen]
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 {
Expand Down Expand Up @@ -81,7 +81,7 @@ as arguments and returns.
```rust
#[wasm_bindgen]
extern "C" {
fn setInterval(closure: &Closure<FnMut()>, millis: u32) -> f64;
fn setInterval(closure: &Closure<dyn FnMut()>, millis: u32) -> f64;
fn cancelInterval(token: f64);

#[wasm_bindgen(js_namespace = console)]
Expand All @@ -90,7 +90,7 @@ extern "C" {

#[wasm_bindgen]
pub struct Interval {
closure: Closure<FnMut()>,
closure: Closure<dyn FnMut()>,
token: f64,
}

Expand Down
2 changes: 1 addition & 1 deletion guide/src/web-sys/type-translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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
`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`.

[webidl]: https://heycam.github.io/webidl/
20 changes: 10 additions & 10 deletions src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use crate::UnwrapThrowExt;
///
/// #[wasm_bindgen]
/// extern "C" {
/// fn setInterval(closure: &Closure<FnMut()>, time: u32) -> i32;
/// fn setInterval(closure: &Closure<dyn FnMut()>, time: u32) -> i32;
/// fn clearInterval(id: i32);
///
/// #[wasm_bindgen(js_namespace = console)]
Expand All @@ -58,7 +58,7 @@ use crate::UnwrapThrowExt;
/// #[wasm_bindgen]
/// pub struct IntervalHandle {
/// interval_id: i32,
/// _closure: Closure<FnMut()>,
/// _closure: Closure<dyn FnMut()>,
/// }
///
/// impl Drop for IntervalHandle {
Expand All @@ -73,7 +73,7 @@ use crate::UnwrapThrowExt;
/// // a JS closure.
/// let cb = Closure::wrap(Box::new(|| {
/// log("interval elapsed!");
/// }) as Box<FnMut()>);
/// }) as Box<dyn FnMut()>);
///
/// // Next we pass this via reference to the `setInterval` function, and
/// // `setInterval` gets a handle to the corresponding JS closure.
Expand Down Expand Up @@ -101,7 +101,7 @@ use crate::UnwrapThrowExt;
/// #[wasm_bindgen]
/// pub struct IntervalHandle {
/// interval_id: i32,
/// _closure: Closure<FnMut()>,
/// _closure: Closure<dyn FnMut()>,
/// }
///
/// impl Drop for IntervalHandle {
Expand All @@ -115,7 +115,7 @@ use crate::UnwrapThrowExt;
/// pub fn run() -> Result<IntervalHandle, JsValue> {
/// let cb = Closure::wrap(Box::new(|| {
/// web_sys::console::log_1(&"inverval elapsed!".into());
/// }) as Box<FnMut()>);
/// }) as Box<dyn FnMut()>);
///
/// let window = web_sys::window().unwrap();
/// let interval_id = window.set_interval_with_callback_and_timeout_and_arguments_0(
Expand Down Expand Up @@ -144,7 +144,7 @@ use crate::UnwrapThrowExt;
///
/// #[wasm_bindgen]
/// extern "C" {
/// fn requestAnimationFrame(closure: &Closure<FnMut()>) -> u32;
/// fn requestAnimationFrame(closure: &Closure<dyn FnMut()>) -> u32;
/// fn cancelAnimationFrame(id: u32);
///
/// #[wasm_bindgen(js_namespace = console)]
Expand All @@ -154,7 +154,7 @@ use crate::UnwrapThrowExt;
/// #[wasm_bindgen]
/// pub struct AnimationFrameHandle {
/// animation_id: u32,
/// _closure: Closure<FnMut()>,
/// _closure: Closure<dyn FnMut()>,
/// }
///
/// impl Drop for AnimationFrameHandle {
Expand Down Expand Up @@ -377,12 +377,12 @@ where

// 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
// `Closure::<FnOnce()>::once(...)`.
// `Closure::<dyn FnOnce()>::once(...)`.
impl Closure<dyn FnOnce()> {
/// 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
/// `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
/// than once.
///
Expand All @@ -404,7 +404,7 @@ impl Closure<dyn FnOnce()> {
///
/// // Create a `Closure` from `f`. Note that the `Closure`'s type parameter
/// // 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>
where
Expand Down
Loading

0 comments on commit 1a7d6de

Please sign in to comment.