Description
Right now wasm-bindgen automatically generates various impls for JS types:
-
AsRef<JsValue> for Foo
-
From<Foo> for JsValue
-
From<JsValue> for Foo
-
JsCast for Foo
All of these are completely fine and reasonable... except for From<JsValue> for Foo
.
The problem is that it is equivalent to JsCast::unchecked_into
, which means it can arbitrarily convert any JS type into Foo
.
This is obviously dangerous, but it does not indicate to the user that it is dangerous: From
is normally used for safe, infallible, lossless conversions.
From a theoretical perspective, doing unchecked upcasting is fundamentally wrong, and from a practical perspective it's very confusing for users. We already have JsCast::unchecked_into
for arbitrary type casts, and it makes it clear that the user is doing something dangerous, so we don't need From<JsValue> for Foo
(which just does the same thing).
This isn't just a theoretical problem: I've seen multiple users get confused about the difference between Uint8Array::new
and Uint8Array::from
. They try to do things like this:
let x = Uint8Array::from(some_array_buffer).to_vec();
This gives the following very cryptic error message:
wasm-bindgen: imported JS function that was not marked as `catch` threw an error: expected a number argument
The correct thing to do is to use Uint8Array::new
, but the user doesn't realize that. They don't realize that Uint8Array::from
is just doing a compile time unchecked type cast, they expected Uint8Array::from
to do an actual runtime conversion.
So I propose deprecating the From<JsValue> for Foo
impls and later in a breaking change removing them entirely.