Auto merge of #8041 - nox:castable, r=jdm

Introduce trait Castable

Removes all those messy FooCast structures in InheritTypes.rs.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8041)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-10-21 07:57:32 -06:00
commit 674589c370
84 changed files with 1193 additions and 1511 deletions

View file

@ -24,6 +24,7 @@
//!
use core::nonzero::NonZero;
use dom::bindings::conversions::{Castable, DerivedFrom};
use dom::bindings::trace::JSTraceable;
use dom::bindings::trace::trace_reflector;
use dom::bindings::utils::{Reflectable, Reflector};
@ -34,6 +35,7 @@ use layout_interface::TrustedNodeAddress;
use script_task::STACK_ROOTS;
use std::cell::UnsafeCell;
use std::default::Default;
use std::mem;
use std::ops::Deref;
use std::ptr;
use util::mem::HeapSizeOf;
@ -112,6 +114,24 @@ pub struct LayoutJS<T> {
ptr: NonZero<*const T>
}
impl<T: Castable> LayoutJS<T> {
/// Cast a DOM object root upwards to one of the interfaces it derives from.
pub fn upcast<U>(&self) -> LayoutJS<U> where U: Castable, T: DerivedFrom<U> {
unsafe { mem::transmute_copy(self) }
}
/// Cast a DOM object downwards to one of the interfaces it might implement.
pub fn downcast<U>(&self) -> Option<LayoutJS<U>> where U: DerivedFrom<T> {
unsafe {
if (*self.unsafe_get()).is::<U>() {
Some(mem::transmute_copy(self))
} else {
None
}
}
}
}
impl<T: Reflectable> LayoutJS<T> {
/// Get the reflector.
pub unsafe fn get_jsobject(&self) -> *mut JSObject {
@ -440,6 +460,22 @@ pub struct Root<T: Reflectable> {
root_list: *const RootCollection,
}
impl<T: Castable> Root<T> {
/// Cast a DOM object root upwards to one of the interfaces it derives from.
pub fn upcast<U>(root: Root<T>) -> Root<U> where U: Castable, T: DerivedFrom<U> {
unsafe { mem::transmute(root) }
}
/// Cast a DOM object root downwards to one of the interfaces it might implement.
pub fn downcast<U>(root: Root<T>) -> Option<Root<U>> where U: DerivedFrom<T> {
if root.is::<U>() {
Some(unsafe { mem::transmute(root) })
} else {
None
}
}
}
impl<T: Reflectable> Root<T> {
/// Create a new stack-bounded root for the provided JS-owned value.
/// It cannot not outlive its associated `RootCollection`, and it gives