Skip to content

Commit

Permalink
Free implementation in alloc if querying fails
Browse files Browse the repository at this point in the history
  • Loading branch information
rylev committed May 11, 2022
1 parent 94d335e commit 92caf84
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
11 changes: 8 additions & 3 deletions crates/libs/implement/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,18 @@ pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro:
}
}
impl <#constraints> #original_ident::<#(#generics,)*> {
fn alloc<ResultType: ::windows::core::Interface>(self) -> ::windows::core::Result<ResultType> {
fn alloc<I: ::windows::core::Interface>(self) -> ::windows::core::Result<I> {
let this = #impl_ident::<#(#generics,)*>::new(self);
let boxed = ::core::mem::ManuallyDrop::new(::std::boxed::Box::new(this));
let mut result = None;
unsafe {
<#impl_ident::<#(#generics,)*> as ::windows::core::IUnknownImpl>::QueryInterface(&*boxed, &ResultType::IID, &mut result as *mut _ as _).and_some(result)
let result = unsafe {
<#impl_ident::<#(#generics,)*> as ::windows::core::IUnknownImpl>::QueryInterface(&*boxed, &I::IID, &mut result as *mut _ as _).and_some(result)
};
// If querying for the supplied interface fails, we must free the underlying implementation, otherwise that memory will be leaked
if result.is_err() {
let _ = ::core::mem::ManuallyDrop::into_inner(boxed);
}
result
}
}
impl <#constraints> ::windows::core::Compose for #original_ident::<#(#generics,)*> {
Expand Down
1 change: 0 additions & 1 deletion crates/tests/nightly_implement/tests/com.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,5 @@ fn mix() -> Result<()> {
let f: IStringable = Mix.alloc()?;
assert!(f.ToString()? == "Mix");


Ok(())
}

0 comments on commit 92caf84

Please sign in to comment.