@@ -54,10 +54,10 @@ pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro:
5454            impl  <#constraints> :: core:: convert:: From <#original_ident:: <#( #generics, ) * >> for  #interface_ident { 
5555                fn  from( this:  #original_ident:: <#( #generics, ) * >)  -> Self  { 
5656                    let  this = #impl_ident:: <#( #generics, ) * >:: new( this) ; 
57-                     let  mut  this = :: std:: boxed:: Box :: new( this) ; 
58-                     let  vtable_ptr = & mut   this. vtables. #offset  as   * mut   * const  <#interface_ident  as   :: windows :: core :: Interface > :: Vtable ; 
59-                     let  _ =  :: std :: boxed :: Box :: leak ( this ) ; 
60-                     unsafe  {  :: core:: mem:: transmute_copy ( & vtable_ptr)  } 
57+                     let  mut  this = :: core :: mem :: ManuallyDrop :: new ( :: std:: boxed:: Box :: new( this) ) ; 
58+                     let  vtable_ptr = & this. vtables. #offset; 
59+                     // SAFETY: interfaces are in-memory equivalent to pointers to their vtables. 
60+                     unsafe  {  :: core:: mem:: transmute ( vtable_ptr)  } 
6161                } 
6262            } 
6363            impl  <#constraints> :: windows:: core:: AsImpl <#original_ident:: <#( #generics, ) * >> for  #interface_ident { 
@@ -145,12 +145,16 @@ pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro:
145145            } 
146146        } 
147147        impl  <#constraints> #original_ident:: <#( #generics, ) * > { 
148-             fn  cast<ResultType :  :: windows:: core:: Interface >( & self )  -> :: windows:: core:: Result <ResultType > { 
149-                 unsafe  { 
150-                     let  boxed = ( self  as  * const  #original_ident:: <#( #generics, ) * > as  * mut  #original_ident:: <#( #generics, ) * > as  * mut  :: windows:: core:: RawPtr ) . sub( 2  + #interfaces_len)  as  * mut  #impl_ident:: <#( #generics, ) * >; 
151-                     let  mut  result = None ; 
152-                     <#impl_ident:: <#( #generics, ) * > as  :: windows:: core:: IUnknownImpl >:: QueryInterface ( & * boxed,  & ResultType :: IID ,  & mut  result as  * mut  _ as  _) . and_some( result) 
153-                 } 
148+             /// Try casting as the provided interface 
149+              /// 
150+              /// # Safety 
151+              /// 
152+              /// This function can only be safely called if `self` has been heap allocated and pinned using 
153+              /// the mechanisms provided by `implement` macro. 
154+              unsafe  fn  cast<I :  :: windows:: core:: Interface >( & self )  -> :: windows:: core:: Result <I > { 
155+                 let  boxed = ( self  as  * const  _ as  * const  :: windows:: core:: RawPtr ) . sub( 2  + #interfaces_len)  as  * mut  #impl_ident:: <#( #generics, ) * >; 
156+                 let  mut  result = None ; 
157+                 <#impl_ident:: <#( #generics, ) * > as  :: windows:: core:: IUnknownImpl >:: QueryInterface ( & * boxed,  & I :: IID ,  & mut  result as  * mut  _ as  _) . and_some( result) 
154158            } 
155159        } 
156160        impl  <#constraints> :: windows:: core:: Compose  for  #original_ident:: <#( #generics, ) * > { 
@@ -163,23 +167,19 @@ pub fn implement(attributes: proc_macro::TokenStream, original_type: proc_macro:
163167        } 
164168        impl  <#constraints> :: core:: convert:: From <#original_ident:: <#( #generics, ) * >> for  :: windows:: core:: IUnknown  { 
165169            fn  from( this:  #original_ident:: <#( #generics, ) * >)  -> Self  { 
170+                 let  this = #impl_ident:: <#( #generics, ) * >:: new( this) ; 
171+                 let  boxed = :: core:: mem:: ManuallyDrop :: new( :: std:: boxed:: Box :: new( this) ) ; 
166172                unsafe  { 
167-                     let  this = #impl_ident:: <#( #generics, ) * >:: new( this) ; 
168-                     let  ptr = :: std:: boxed:: Box :: into_raw( :: std:: boxed:: Box :: new( this) ) ; 
169-                     :: core:: mem:: transmute_copy( & :: core:: ptr:: NonNull :: new_unchecked( 
170-                         & mut  ( * ptr) . identity as  * mut  _ as  _
171-                     ) ) 
173+                     :: core:: mem:: transmute( & boxed. identity) 
172174                } 
173175            } 
174176        } 
175177        impl  <#constraints> :: core:: convert:: From <#original_ident:: <#( #generics, ) * >> for  :: windows:: core:: IInspectable  { 
176178            fn  from( this:  #original_ident:: <#( #generics, ) * >)  -> Self  { 
179+                 let  this = #impl_ident:: <#( #generics, ) * >:: new( this) ; 
180+                 let  boxed = :: core:: mem:: ManuallyDrop :: new( :: std:: boxed:: Box :: new( this) ) ; 
177181                unsafe  { 
178-                     let  this = #impl_ident:: <#( #generics, ) * >:: new( this) ; 
179-                     let  ptr = :: std:: boxed:: Box :: into_raw( :: std:: boxed:: Box :: new( this) ) ; 
180-                     :: core:: mem:: transmute_copy( & :: core:: ptr:: NonNull :: new_unchecked( 
181-                         & mut  ( * ptr) . identity as  * mut  _ as  _
182-                     ) ) 
182+                     :: core:: mem:: transmute( & boxed. identity) 
183183                } 
184184            } 
185185        } 
0 commit comments