Skip to main content

wasm_bindgen/rt/
marker.rs

1/// Marker trait for types that support `#[wasm_bindgen(constructor)]`.
2#[cfg_attr(
3    wbg_diagnostic,
4    diagnostic::on_unimplemented(
5        message = "JavaScript constructors are not supported for `{Self}`",
6        label = "this function cannot be the constructor of `{Self}`",
7        note = "`#[wasm_bindgen(constructor)]` is only supported for `struct`s and cannot be used for `enum`s.",
8        note = "Consider removing the `constructor` option and using a regular static method instead."
9    )
10)]
11pub trait SupportsConstructor {}
12pub struct CheckSupportsConstructor<T: SupportsConstructor>(T);
13
14/// Marker trait for types that support `#[wasm_bindgen(getter)]` or
15/// `#[wasm_bindgen(Setter)]` on instance methods.
16#[cfg_attr(
17    wbg_diagnostic,
18    diagnostic::on_unimplemented(
19        message = "JavaScript instance getters and setters are not supported for `{Self}`",
20        label = "this method cannot be a getter or setter for `{Self}`",
21        note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s.",
22    )
23)]
24pub trait SupportsInstanceProperty {}
25pub struct CheckSupportsInstanceProperty<T: SupportsInstanceProperty>(T);
26
27/// Marker trait for types that support `#[wasm_bindgen(getter)]` or
28/// `#[wasm_bindgen(Setter)]` on static methods.
29#[cfg_attr(
30    wbg_diagnostic,
31    diagnostic::on_unimplemented(
32        message = "JavaScript static getters and setters are not supported for `{Self}`",
33        label = "this static function cannot be a static getter or setter on `{Self}`",
34        note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s.",
35    )
36)]
37pub trait SupportsStaticProperty {}
38pub struct CheckSupportsStaticProperty<T: SupportsStaticProperty>(T);
39
40#[cfg(all(
41    feature = "std",
42    all(target_family = "wasm", not(target_os = "wasi")),
43    panic = "unwind"
44))]
45use core::panic::UnwindSafe;
46
47/// Seal for `wasm_bindgen::JsStringLike`: only string shapes provided by
48/// `wasm-bindgen` and `js-sys` may implement it.
49pub trait JsStringLikeSealed {}
50
51/// Seal for `wasm_bindgen::convert::VectorRefIntoWasmAbi`: only sequences
52/// declared by `wasm-bindgen`, `js-sys` and generated bindings may implement
53/// it.
54pub trait VectorRefIntoWasmAbiSealed {}
55
56/// Marker trait for types that are UnwindSafe only when building with panic unwind
57pub trait MaybeUnwindSafe {}
58
59#[cfg(all(
60    feature = "std",
61    all(target_family = "wasm", not(target_os = "wasi")),
62    panic = "unwind"
63))]
64impl<T: UnwindSafe + ?Sized> MaybeUnwindSafe for T {}
65
66#[cfg(not(all(
67    feature = "std",
68    all(target_family = "wasm", not(target_os = "wasi")),
69    panic = "unwind"
70)))]
71impl<T: ?Sized> MaybeUnwindSafe for T {}
72
73/// Private marker trait for erasable generics - types with this trait have the same
74/// repr for all generic param values, and can therefore be transmuted on
75/// the singular Repr type representation on ABI boundaries.
76///
77/// # Safety
78/// This type must only be implemented on types known to be repr equivalent
79/// to their Repr type.
80// #[cfg_attr(
81//     wbg_diagnostic,
82//     diagnostic::on_unimplemented(
83//         label = "generic parameter is not a valid Wasm Bindgen ErasableGeneric type",
84//         note = "\nRecommendation: Add the direct `: wasm_bindgen::JsGeneric` convenience trait bound for JsValue generics, instead of `ErasableGeneric`.\n",
85//     )
86// )]
87pub unsafe trait ErasableGeneric {
88    /// The singular concrete type that all generic variants can be transmuted on.
89    ///
90    /// For reference types this deliberately carries the borrow lifetime (rather
91    /// than erasing it to `'static`). The lifetime-faithful repr is what makes
92    /// [`Upcast::upcast`](crate::convert::Upcast::upcast) and
93    /// [`upcast_into`](crate::convert::Upcast::upcast_into) sound: the
94    /// `Repr`-equality bound then rejects upcasts that would launder a
95    /// short-lived borrow into a longer one. The `'static` erasure that the JS
96    /// ABI boundary relies on (where borrows are only ever call-scoped) is
97    /// instead performed explicitly via an `unsafe` cast in codegen.
98    type Repr;
99}
100
101unsafe impl<'b, T: ErasableGeneric> ErasableGeneric for &'b mut T
102where
103    <T as ErasableGeneric>::Repr: 'b,
104{
105    type Repr = &'b mut T::Repr;
106}
107
108unsafe impl<'b, T: ErasableGeneric> ErasableGeneric for &'b T
109where
110    <T as ErasableGeneric>::Repr: 'b,
111{
112    type Repr = &'b T::Repr;
113}
114
115/// Trait bound marker for types that are passed as an own generic type.
116/// Encapsulating the ErasableGeneric invariant that must be maintained, that
117/// the repr of the type is the type of the concrete target type repr.
118/// This is useful to provide simple debuggable trait bounds for codegen.
119#[cfg_attr(
120    wbg_diagnostic,
121    diagnostic::on_unimplemented(
122        message = "Unable to call function, since the concrete generic argument or return value cannot be type-erased into the expected generic repr type for the function",
123        label = "passed concrete generic type does not match the expected generic repr type",
124        note = "Make sure that all erasable generic parameters satisfy the trait bound `ErasableGeneric` with the correct repr. Wasm Bindgen generic parameters and return values for functions are defined to work for specific type-erasable generic repr types only.",
125    )
126)]
127pub trait ErasableGenericOwn<ConcreteTarget>: ErasableGeneric {}
128
129impl<T, ConcreteTarget> ErasableGenericOwn<ConcreteTarget> for T
130where
131    ConcreteTarget: ErasableGeneric,
132    T: ErasableGeneric<Repr = <ConcreteTarget as ErasableGeneric>::Repr>,
133{
134}
135
136/// Trait bound marker for types that are passed as a borrowed generic type.
137/// Encapsulating the ErasableGeneric invariant that must be maintained, that
138/// the repr of the type is the type of the concrete target type repr.
139/// This is useful to provide simple debuggable trait bounds for codegen.
140#[cfg_attr(
141    wbg_diagnostic,
142    diagnostic::on_unimplemented(
143        message = "Unable to call this function, since the concrete generic argument or return value cannot be type-erased into the expected generic repr type for the function",
144        label = "concrete generic type does not match the expected generic repr type",
145        note = "Make sure that all erasable generic parameters satisfy the trait bound `ErasableGeneric` with the correct repr. Wasm Bindgen generic parameters and return values for functions are defined to work for specific type-erasable generic repr types only.",
146    )
147)]
148pub trait ErasableGenericBorrow<Target: ?Sized> {}
149
150impl<'a, T: ?Sized + 'a, ConcreteTarget: ?Sized + 'a> ErasableGenericBorrow<ConcreteTarget> for T
151where
152    &'a ConcreteTarget: ErasableGeneric,
153    &'a T: ErasableGeneric<Repr = <&'a ConcreteTarget as ErasableGeneric>::Repr>,
154{
155}
156
157/// Trait bound marker for types that are passed as a mutable borrowed generic type.
158/// Encapsulating the ErasableGeneric invariant that must be maintained, that
159/// the repr of the type is the type of the concrete target type repr.
160/// This is useful to provide simple debuggable trait bounds for codegen.
161#[cfg_attr(
162    wbg_diagnostic,
163    diagnostic::on_unimplemented(
164        message = "Unable to call this function, since the concrete generic argument or return value cannot be type-erased into the expected generic repr type for the function",
165        label = "concrete generic type does not match the expected generic repr type",
166        note = "Make sure that all erasable generic parameters satisfy the trait bound `ErasableGeneric` with the correct repr. Wasm Bindgen generic parameters and return values for functions are defined to work for specific type-erasable generic repr types only.",
167    )
168)]
169pub trait ErasableGenericBorrowMut<Target: ?Sized> {}
170
171impl<'a, T: ?Sized + 'a, ConcreteTarget: ?Sized + 'a> ErasableGenericBorrowMut<ConcreteTarget> for T
172where
173    &'a mut ConcreteTarget: ErasableGeneric,
174    &'a mut T: ErasableGeneric<Repr = <&'a mut ConcreteTarget as ErasableGeneric>::Repr>,
175{
176}