Skip to content

Deprecate all From upcast impls #2059

Open
@Pauan

Description

@Pauan

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking-changeTracking breaking changes for the next major version bump (if ever)js-sysIssues related to the `js-sys` crateweb-sysIssues related to the `web-sys` crate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions