@@ -11,8 +11,9 @@ use w::um::combaseapi::CoTaskMemFree;
1111
1212/// Smart pointer for Windows Runtime objects. This pointer automatically maintains the
1313/// reference count of the underlying COM object.
14- #[ repr( C ) ] #[ derive( Debug ) ]
15- pub struct ComPtr < T > ( * mut T ) ; // TODO: use ptr::NonNull<T> when stabilized (and lang-compat feature is disabled), see https://github.com/rust-lang/rust/issues/27730
14+ #[ repr( transparent) ]
15+ #[ derive( Debug ) ]
16+ pub struct ComPtr < T > ( ptr:: NonNull < T > ) ;
1617
1718impl < T > fmt:: Pointer for ComPtr < T > {
1819 #[ inline]
@@ -48,7 +49,7 @@ impl<T> ComPtr<T> {
4849 #[ inline]
4950 pub unsafe fn wrap ( ptr : * mut T ) -> ComPtr < T > { // TODO: Add T: ComInterface bound
5051 debug_assert ! ( !ptr. is_null( ) ) ;
51- ComPtr ( ptr)
52+ ComPtr ( ptr:: NonNull :: new_unchecked ( ptr ) )
5253 }
5354
5455 /// Creates an optional `ComPtr` to wrap a raw pointer that may be null.
@@ -59,20 +60,20 @@ impl<T> ComPtr<T> {
5960 if ptr. is_null ( ) {
6061 None
6162 } else {
62- Some ( ComPtr ( ptr) )
63+ Some ( ComPtr ( ptr:: NonNull :: new_unchecked ( ptr ) ) )
6364 }
6465 }
6566
6667 /// Returns the underlying WinRT object as a reference to an `IInspectable` object.
6768 #[ inline]
6869 fn as_inspectable ( & self ) -> & mut IInspectable where T : RtInterface {
69- unsafe { & mut * ( self . 0 as * mut IInspectable ) }
70+ unsafe { & mut * ( self . 0 . as_ptr ( ) as * mut IInspectable ) }
7071 }
7172
7273 /// Returns the underlying WinRT or COM object as a reference to an `IUnknown` object.
7374 #[ inline]
7475 fn as_unknown ( & self ) -> & mut IUnknown {
75- unsafe { & mut * ( self . 0 as * mut IUnknown ) }
76+ unsafe { & mut * ( self . 0 . as_ptr ( ) as * mut IUnknown ) }
7677 }
7778
7879 /// Changes the type of the underlying COM object to a different interface without doing `QueryInterface`.
@@ -116,21 +117,21 @@ impl<T> Deref for ComPtr<T> {
116117
117118 #[ inline]
118119 fn deref ( & self ) -> & T {
119- unsafe { & * self . 0 }
120+ unsafe { self . 0 . as_ref ( ) }
120121 }
121122}
122123impl < T > DerefMut for ComPtr < T > {
123124 #[ inline]
124125 fn deref_mut ( & mut self ) -> & mut T {
125- unsafe { & mut * self . 0 }
126+ unsafe { self . 0 . as_mut ( ) }
126127 }
127128}
128129impl < T > Clone for ComPtr < T > {
129130 #[ inline]
130131 fn clone ( & self ) -> Self {
131132 unsafe {
132133 self . as_unknown ( ) . AddRef ( ) ;
133- ComPtr :: wrap ( self . 0 )
134+ ComPtr :: wrap ( self . 0 . as_ptr ( ) )
134135 }
135136 }
136137}
@@ -152,7 +153,7 @@ impl<T> PartialEq<ComPtr<T>> for ComPtr<T> {
152153/// using `CoTaskMemFree` on drop.
153154pub struct ComArray < T > where T : :: RtType {
154155 size : u32 ,
155- first : * mut T :: Abi
156+ first : ptr :: NonNull < T :: Abi >
156157}
157158
158159impl < T > ComArray < T > where T : :: RtType {
@@ -161,7 +162,7 @@ impl<T> ComArray<T> where T: ::RtType {
161162 assert ! ( !first. is_null( ) ) ;
162163 ComArray {
163164 size : size,
164- first : first
165+ first : ptr :: NonNull :: new_unchecked ( first)
165166 }
166167 }
167168
@@ -176,13 +177,13 @@ impl<T> Deref for ComArray<T> where T: ::RtType {
176177 type Target = [ T :: OutNonNull ] ;
177178 #[ inline]
178179 fn deref ( & self ) -> & [ T :: OutNonNull ] {
179- unsafe { :: std:: slice:: from_raw_parts ( self . first as * mut T :: OutNonNull , self . size as usize ) }
180+ unsafe { :: std:: slice:: from_raw_parts ( self . first . as_ptr ( ) as * mut T :: OutNonNull , self . size as usize ) }
180181 }
181182}
182183impl < T > DerefMut for ComArray < T > where T : :: RtType {
183184 #[ inline]
184185 fn deref_mut ( & mut self ) -> & mut [ T :: OutNonNull ] {
185- unsafe { :: std:: slice:: from_raw_parts_mut ( self . first as * mut T :: OutNonNull , self . size as usize ) }
186+ unsafe { :: std:: slice:: from_raw_parts_mut ( self . first . as_ptr ( ) as * mut T :: OutNonNull , self . size as usize ) }
186187 }
187188}
188189
@@ -191,7 +192,7 @@ impl<T> Drop for ComArray<T> where T: ::RtType {
191192 fn drop ( & mut self ) {
192193 unsafe {
193194 :: std:: ptr:: drop_in_place ( & mut self [ ..] ) ;
194- CoTaskMemFree ( self . first as LPVOID )
195+ CoTaskMemFree ( self . first . as_ptr ( ) as LPVOID )
195196 } ;
196197 }
197198}
@@ -216,8 +217,6 @@ mod tests {
216217
217218 // make sure that ComPtr is pointer-sized
218219 assert_eq ! ( size_of:: <:: ComPtr <:: IInspectable >>( ) , size_of:: <* mut :: IInspectable >( ) ) ;
219-
220- // TODO: enable this once the null-pointer optimization can be used for Option<ComPtr>
221- //assert_eq!(size_of::<Option<::ComPtr<::IInspectable>>>(), size_of::<*mut ::IInspectable>());
220+ assert_eq ! ( size_of:: <Option <:: ComPtr <:: IInspectable >>>( ) , size_of:: <* mut :: IInspectable >( ) ) ;
222221 }
223- }
222+ }
0 commit comments