@@ -11,8 +11,9 @@ use w::um::combaseapi::CoTaskMemFree;
11
11
12
12
/// Smart pointer for Windows Runtime objects. This pointer automatically maintains the
13
13
/// 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 > ) ;
16
17
17
18
impl < T > fmt:: Pointer for ComPtr < T > {
18
19
#[ inline]
@@ -48,7 +49,7 @@ impl<T> ComPtr<T> {
48
49
#[ inline]
49
50
pub unsafe fn wrap ( ptr : * mut T ) -> ComPtr < T > { // TODO: Add T: ComInterface bound
50
51
debug_assert ! ( !ptr. is_null( ) ) ;
51
- ComPtr ( ptr)
52
+ ComPtr ( ptr:: NonNull :: new_unchecked ( ptr ) )
52
53
}
53
54
54
55
/// Creates an optional `ComPtr` to wrap a raw pointer that may be null.
@@ -59,20 +60,20 @@ impl<T> ComPtr<T> {
59
60
if ptr. is_null ( ) {
60
61
None
61
62
} else {
62
- Some ( ComPtr ( ptr) )
63
+ Some ( ComPtr ( ptr:: NonNull :: new_unchecked ( ptr ) ) )
63
64
}
64
65
}
65
66
66
67
/// Returns the underlying WinRT object as a reference to an `IInspectable` object.
67
68
#[ inline]
68
69
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 ) }
70
71
}
71
72
72
73
/// Returns the underlying WinRT or COM object as a reference to an `IUnknown` object.
73
74
#[ inline]
74
75
fn as_unknown ( & self ) -> & mut IUnknown {
75
- unsafe { & mut * ( self . 0 as * mut IUnknown ) }
76
+ unsafe { & mut * ( self . 0 . as_ptr ( ) as * mut IUnknown ) }
76
77
}
77
78
78
79
/// 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> {
116
117
117
118
#[ inline]
118
119
fn deref ( & self ) -> & T {
119
- unsafe { & * self . 0 }
120
+ unsafe { self . 0 . as_ref ( ) }
120
121
}
121
122
}
122
123
impl < T > DerefMut for ComPtr < T > {
123
124
#[ inline]
124
125
fn deref_mut ( & mut self ) -> & mut T {
125
- unsafe { & mut * self . 0 }
126
+ unsafe { self . 0 . as_mut ( ) }
126
127
}
127
128
}
128
129
impl < T > Clone for ComPtr < T > {
129
130
#[ inline]
130
131
fn clone ( & self ) -> Self {
131
132
unsafe {
132
133
self . as_unknown ( ) . AddRef ( ) ;
133
- ComPtr :: wrap ( self . 0 )
134
+ ComPtr :: wrap ( self . 0 . as_ptr ( ) )
134
135
}
135
136
}
136
137
}
@@ -152,7 +153,7 @@ impl<T> PartialEq<ComPtr<T>> for ComPtr<T> {
152
153
/// using `CoTaskMemFree` on drop.
153
154
pub struct ComArray < T > where T : :: RtType {
154
155
size : u32 ,
155
- first : * mut T :: Abi
156
+ first : ptr :: NonNull < T :: Abi >
156
157
}
157
158
158
159
impl < T > ComArray < T > where T : :: RtType {
@@ -161,7 +162,7 @@ impl<T> ComArray<T> where T: ::RtType {
161
162
assert ! ( !first. is_null( ) ) ;
162
163
ComArray {
163
164
size : size,
164
- first : first
165
+ first : ptr :: NonNull :: new_unchecked ( first)
165
166
}
166
167
}
167
168
@@ -176,13 +177,13 @@ impl<T> Deref for ComArray<T> where T: ::RtType {
176
177
type Target = [ T :: OutNonNull ] ;
177
178
#[ inline]
178
179
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 ) }
180
181
}
181
182
}
182
183
impl < T > DerefMut for ComArray < T > where T : :: RtType {
183
184
#[ inline]
184
185
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 ) }
186
187
}
187
188
}
188
189
@@ -191,7 +192,7 @@ impl<T> Drop for ComArray<T> where T: ::RtType {
191
192
fn drop ( & mut self ) {
192
193
unsafe {
193
194
:: std:: ptr:: drop_in_place ( & mut self [ ..] ) ;
194
- CoTaskMemFree ( self . first as LPVOID )
195
+ CoTaskMemFree ( self . first . as_ptr ( ) as LPVOID )
195
196
} ;
196
197
}
197
198
}
@@ -216,8 +217,6 @@ mod tests {
216
217
217
218
// make sure that ComPtr is pointer-sized
218
219
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 >( ) ) ;
222
221
}
223
- }
222
+ }
0 commit comments