Skip to content

Commit efdbbc8

Browse files
committed
Add back cast but make it unsafe
1 parent 92caf84 commit efdbbc8

File tree

4 files changed

+17
-3
lines changed

4 files changed

+17
-3
lines changed

crates/libs/implement/src/lib.rs

+14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use tokens::*;
88
pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro::TokenStream) -> proc_macro::TokenStream {
99
let attributes = syn::parse_macro_input!(attributes as ImplementAttributes);
1010
let generics = attributes.generics();
11+
let interfaces_len = Literal::usize_unsuffixed(attributes.implement.len());
1112

1213
let constraints = quote! {
1314
#(#generics: ::windows::core::RuntimeType + 'static,)*
@@ -144,6 +145,7 @@ pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro:
144145
}
145146
}
146147
impl <#constraints> #original_ident::<#(#generics,)*> {
148+
/// Box and pin `self` and then try to cast it as the supplied interface
147149
fn alloc<I: ::windows::core::Interface>(self) -> ::windows::core::Result<I> {
148150
let this = #impl_ident::<#(#generics,)*>::new(self);
149151
let boxed = ::core::mem::ManuallyDrop::new(::std::boxed::Box::new(this));
@@ -157,6 +159,18 @@ pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro:
157159
}
158160
result
159161
}
162+
163+
/// Try casting as the provided interface
164+
///
165+
/// # Safety
166+
///
167+
/// This function can only be safely called if `self` has been heap allocated and pinned using
168+
/// the mechanisms provided by `implement` macro.
169+
unsafe fn cast<I: ::windows::core::Interface>(&self) -> ::windows::core::Result<I> {
170+
let boxed = (self as *const _ as *const ::windows::core::RawPtr).sub(2 + #interfaces_len) as *mut #impl_ident::<#(#generics,)*>;
171+
let mut result = None;
172+
<#impl_ident::<#(#generics,)*> as ::windows::core::IUnknownImpl>::QueryInterface(&*boxed, &I::IID, &mut result as *mut _ as _).and_some(result)
173+
}
160174
}
161175
impl <#constraints> ::windows::core::Compose for #original_ident::<#(#generics,)*> {
162176
unsafe fn compose<'a>(implementation: Self) -> (::windows::core::IInspectable, &'a mut ::core::option::Option<::windows::core::IInspectable>) {

crates/tests/nightly_implement/tests/cast_self.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct App;
1010
#[allow(non_snake_case)]
1111
impl IApplicationOverrides_Impl for App {
1212
fn OnLaunched(&self, _: &Option<LaunchActivatedEventArgs>) -> Result<()> {
13-
let app: Application = self.cast()?;
13+
let app: Application = unsafe { self.cast()? };
1414
assert!(app.FocusVisualKind()? == FocusVisualKind::DottedLine);
1515
Ok(())
1616
}

crates/tests/nightly_implement/tests/into_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ where
5454
#[allow(non_snake_case)]
5555
impl<T: RuntimeType + 'static> IIterable_Impl<T> for Iterable<T> {
5656
fn First(&self) -> Result<IIterator<T>> {
57-
Ok(Iterator::<T>((self.cast()?, 0).into()).into())
57+
Ok(Iterator::<T>((unsafe { self.cast()? }, 0).into()).into())
5858
}
5959
}
6060

crates/tests/nightly_vector/tests/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<T: ::windows::core::RuntimeType + 'static> IVector_Impl<T> for Vector<T> {
6161
self.Size()
6262
}
6363
fn GetView(&self) -> Result<windows::Foundation::Collections::IVectorView<T>> {
64-
self.cast()
64+
unsafe { self.cast() }
6565
}
6666
fn IndexOf(&self, value: &T::DefaultType, result: &mut u32) -> Result<bool> {
6767
self.IndexOf(value, result)

0 commit comments

Comments
 (0)