mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-24 06:33:33 +03:00
Remove casting to &mut T
for JS casts
I discussed this with @fitzgen awhile back and this sort of casting seems especially problematic when you have code along the lines of: let mut x: HtmlElement = ...; { let y: &mut JsValue = x.as_ref(); *y = 3.into(); } x.some_html_element_method(); as that will immediately throw! We didn't have a use case for mutable casting other than consistency, so this commit removes it for now. We can possibly add it back in later if motivated, but for now it seems reasonable to try to avoid these sorts of pitfalls!
This commit is contained in:
parent
8ce7465bba
commit
9729efe50e
@ -618,9 +618,6 @@ impl ToTokens for ast::ImportType {
|
||||
fn as_ref(&self) -> &JsValue { &self.obj }
|
||||
}
|
||||
|
||||
impl AsMut<JsValue> for #rust_name {
|
||||
fn as_mut(&mut self) -> &mut JsValue { &mut self.obj }
|
||||
}
|
||||
|
||||
impl From<#rust_name> for JsValue {
|
||||
fn from(obj: #rust_name) -> JsValue {
|
||||
@ -656,12 +653,6 @@ impl ToTokens for ast::ImportType {
|
||||
// wrapper around `val`
|
||||
unsafe { &*(val as *const JsValue as *const #rust_name) }
|
||||
}
|
||||
|
||||
fn unchecked_from_js_mut(val: &mut JsValue) -> &mut Self {
|
||||
// Should be safe because `#rust_name` is a transparent
|
||||
// wrapper around `val`
|
||||
unsafe { &mut *(val as *mut JsValue as *mut #rust_name) }
|
||||
}
|
||||
}
|
||||
|
||||
()
|
||||
@ -683,13 +674,6 @@ impl ToTokens for ast::ImportType {
|
||||
#superclass::unchecked_from_js_ref(self.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<#superclass> for #rust_name {
|
||||
fn as_mut(&mut self) -> &mut #superclass {
|
||||
use wasm_bindgen::JsCast;
|
||||
#superclass::unchecked_from_js_mut(self.as_mut())
|
||||
}
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
@ -1191,9 +1175,6 @@ impl ToTokens for ast::Dictionary {
|
||||
impl AsRef<JsValue> for #name {
|
||||
fn as_ref(&self) -> &JsValue { self.obj.as_ref() }
|
||||
}
|
||||
impl AsMut<JsValue> for #name {
|
||||
fn as_mut(&mut self) -> &mut JsValue { self.obj.as_mut() }
|
||||
}
|
||||
|
||||
// Boundary conversion impls
|
||||
impl WasmDescribe for #name {
|
||||
@ -1257,10 +1238,6 @@ impl ToTokens for ast::Dictionary {
|
||||
fn unchecked_from_js_ref(val: &JsValue) -> &Self {
|
||||
unsafe { &*(val as *const JsValue as *const #name) }
|
||||
}
|
||||
|
||||
fn unchecked_from_js_mut(val: &mut JsValue) -> &mut Self {
|
||||
unsafe { &mut *(val as *mut JsValue as *mut #name) }
|
||||
}
|
||||
}
|
||||
};
|
||||
}).to_tokens(tokens);
|
||||
|
48
src/cast.rs
48
src/cast.rs
@ -14,7 +14,7 @@ use JsValue;
|
||||
/// [rfc]: https://github.com/rustwasm/rfcs/pull/2
|
||||
pub trait JsCast
|
||||
where
|
||||
Self: AsRef<JsValue> + AsMut<JsValue> + Into<JsValue>,
|
||||
Self: AsRef<JsValue> + Into<JsValue>,
|
||||
{
|
||||
/// Test whether this JS value is an instance of the type `T`.
|
||||
///
|
||||
@ -61,24 +61,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a dynamic cast (checked at runtime) of this value into the
|
||||
/// target type `T`.
|
||||
///
|
||||
/// This method will return `None` is `self.is_instance_of::<T>()`
|
||||
/// returns `false`, and otherwise it will return `Some(&mut T)`
|
||||
/// manufactured with an unchecked cast (verified correct via the
|
||||
/// `instanceof` operation).
|
||||
fn dyn_mut<T>(&mut self) -> Option<&mut T>
|
||||
where
|
||||
T: JsCast,
|
||||
{
|
||||
if self.is_instance_of::<T>() {
|
||||
Some(self.unchecked_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a zero-cost unchecked cast into the specified type.
|
||||
///
|
||||
/// This method will convert the `self` value to the type `T`, where both
|
||||
@ -111,24 +93,6 @@ where
|
||||
T::unchecked_from_js_ref(self.as_ref())
|
||||
}
|
||||
|
||||
/// Performs a zero-cost unchecked cast into a mutable reference to the
|
||||
/// specified type.
|
||||
///
|
||||
/// This method will convert the `self` value to the type `T`, where both
|
||||
/// `self` and `T` are simple wrappers around `JsValue`. This method **does
|
||||
/// not check whether `self` is an instance of `T`**. If used incorrectly
|
||||
/// then this method may cause runtime exceptions in both Rust and JS, this
|
||||
/// should be used with caution.
|
||||
///
|
||||
/// This method, unlike `unchecked_into`, does not consume ownership of
|
||||
/// `self` and instead works over a utable reference.
|
||||
fn unchecked_mut<T>(&mut self) -> &mut T
|
||||
where
|
||||
T: JsCast,
|
||||
{
|
||||
T::unchecked_from_js_mut(self.as_mut())
|
||||
}
|
||||
|
||||
/// Performs a dynamic `instanceof` check to see whether the `JsValue`
|
||||
/// provided is an instance of this type.
|
||||
///
|
||||
@ -152,14 +116,4 @@ where
|
||||
/// This is intended to be an internal implementation detail, you likely
|
||||
/// won't need to call this.
|
||||
fn unchecked_from_js_ref(val: &JsValue) -> &Self;
|
||||
|
||||
/// Performs a zero-cost unchecked conversion from a `&mut JsValue` into an
|
||||
/// instance of `&mut Self`.
|
||||
///
|
||||
/// Note the safety of this method, which basically means that `Self` must
|
||||
/// be a newtype wrapper around `JsValue`.
|
||||
///
|
||||
/// This is intended to be an internal implementation detail, you likely
|
||||
/// won't need to call this.
|
||||
fn unchecked_from_js_mut(val: &mut JsValue) -> &mut Self;
|
||||
}
|
||||
|
@ -370,11 +370,6 @@ impl JsCast for JsValue {
|
||||
fn instanceof(_val: &JsValue) -> bool { true }
|
||||
fn unchecked_from_js(val: JsValue) -> Self { val }
|
||||
fn unchecked_from_js_ref(val: &JsValue) -> &Self { val }
|
||||
fn unchecked_from_js_mut(val: &mut JsValue) -> &mut Self { val }
|
||||
}
|
||||
|
||||
impl AsMut<JsValue> for JsValue {
|
||||
fn as_mut(&mut self) -> &mut JsValue { self }
|
||||
}
|
||||
|
||||
impl AsRef<JsValue> for JsValue {
|
||||
|
Loading…
Reference in New Issue
Block a user