@@ -39,6 +39,7 @@ use alloc::string::ToString;
39
39
use core:: mem;
40
40
use core:: mem:: ManuallyDrop ;
41
41
use core:: ptr;
42
+ use core:: ptr:: NonNull ;
42
43
use std:: ffi:: CString ;
43
44
44
45
use crate :: runtime:: { Bool , Class , Imp , Object , Protocol , Sel } ;
@@ -120,7 +121,7 @@ fn log2_align_of<T>() -> u8 {
120
121
/// before registering it.
121
122
#[ derive( Debug ) ]
122
123
pub struct ClassDecl {
123
- cls : * mut Class ,
124
+ cls : NonNull < Class > ,
124
125
}
125
126
126
127
// SAFETY: The stuff that touch global state does so using locks internally.
@@ -138,23 +139,23 @@ unsafe impl Send for ClassDecl {}
138
139
unsafe impl Sync for ClassDecl { }
139
140
140
141
impl ClassDecl {
141
- fn with_superclass ( name : & str , superclass : Option < & Class > ) -> Option < ClassDecl > {
142
+ fn as_ptr ( & self ) -> * mut ffi:: objc_class {
143
+ self . cls . as_ptr ( ) . cast ( )
144
+ }
145
+
146
+ fn with_superclass ( name : & str , superclass : Option < & Class > ) -> Option < Self > {
142
147
let name = CString :: new ( name) . unwrap ( ) ;
143
148
let super_ptr = superclass. map_or ( ptr:: null ( ) , |c| c) as _ ;
144
149
let cls = unsafe { ffi:: objc_allocateClassPair ( super_ptr, name. as_ptr ( ) , 0 ) } ;
145
- if cls. is_null ( ) {
146
- None
147
- } else {
148
- Some ( ClassDecl { cls : cls as _ } )
149
- }
150
+ NonNull :: new ( cls. cast ( ) ) . map ( |cls| Self { cls } )
150
151
}
151
152
152
153
/// Constructs a [`ClassDecl`] with the given name and superclass.
153
154
///
154
155
/// Returns [`None`] if the class couldn't be allocated, or a class with
155
156
/// that name already exist.
156
- pub fn new ( name : & str , superclass : & Class ) -> Option < ClassDecl > {
157
- ClassDecl :: with_superclass ( name, Some ( superclass) )
157
+ pub fn new ( name : & str , superclass : & Class ) -> Option < Self > {
158
+ Self :: with_superclass ( name, Some ( superclass) )
158
159
}
159
160
160
161
/// Constructs a [`ClassDecl`] declaring a new root class with the given
@@ -171,12 +172,10 @@ impl ClassDecl {
171
172
/// the entire `NSObject` protocol is implemented.
172
173
/// Functionality it expects, like implementations of `-retain` and
173
174
/// `-release` used by ARC, will not be present otherwise.
174
- pub fn root ( name : & str , intitialize_fn : extern "C" fn ( & Class , Sel ) ) -> Option < ClassDecl > {
175
- let mut decl = ClassDecl :: with_superclass ( name, None ) ;
175
+ pub fn root ( name : & str , intitialize_fn : extern "C" fn ( & Class , Sel ) ) -> Option < Self > {
176
+ let mut decl = Self :: with_superclass ( name, None ) ;
176
177
if let Some ( ref mut decl) = decl {
177
- unsafe {
178
- decl. add_class_method ( sel ! ( initialize) , intitialize_fn) ;
179
- }
178
+ unsafe { decl. add_class_method ( sel ! ( initialize) , intitialize_fn) } ;
180
179
}
181
180
decl
182
181
}
@@ -209,7 +208,7 @@ impl ClassDecl {
209
208
let types = method_type_encoding ( & F :: Ret :: ENCODING , encs) ;
210
209
let success = Bool :: from_raw ( unsafe {
211
210
ffi:: class_addMethod (
212
- self . cls as _ ,
211
+ self . as_ptr ( ) ,
213
212
sel. as_ptr ( ) as _ ,
214
213
Some ( func. imp ( ) ) ,
215
214
types. as_ptr ( ) ,
@@ -244,7 +243,7 @@ impl ClassDecl {
244
243
) ;
245
244
246
245
let types = method_type_encoding ( & F :: Ret :: ENCODING , encs) ;
247
- let metaclass = unsafe { & * self . cls } . metaclass ( ) as * const _ as * mut _ ;
246
+ let metaclass = unsafe { self . cls . as_ref ( ) } . metaclass ( ) as * const _ as * mut _ ;
248
247
let success = Bool :: from_raw ( unsafe {
249
248
ffi:: class_addMethod (
250
249
metaclass,
@@ -268,7 +267,7 @@ impl ClassDecl {
268
267
let align = log2_align_of :: < T > ( ) ;
269
268
let success = Bool :: from_raw ( unsafe {
270
269
ffi:: class_addIvar (
271
- self . cls as _ ,
270
+ self . as_ptr ( ) ,
272
271
c_name. as_ptr ( ) ,
273
272
size,
274
273
align,
@@ -284,7 +283,7 @@ impl ClassDecl {
284
283
///
285
284
/// If the protocol wasn't successfully added.
286
285
pub fn add_protocol ( & mut self , proto : & Protocol ) {
287
- let success = unsafe { ffi:: class_addProtocol ( self . cls as _ , proto. as_ptr ( ) ) } ;
286
+ let success = unsafe { ffi:: class_addProtocol ( self . as_ptr ( ) , proto. as_ptr ( ) ) } ;
288
287
let success = Bool :: from_raw ( success) . as_bool ( ) ;
289
288
assert ! ( success, "Failed to add protocol {:?}" , proto) ;
290
289
}
@@ -296,40 +295,40 @@ impl ClassDecl {
296
295
pub fn register ( self ) -> & ' static Class {
297
296
// Forget self, otherwise the class will be disposed in drop
298
297
let cls = ManuallyDrop :: new ( self ) . cls ;
299
- unsafe { ffi:: objc_registerClassPair ( cls as _ ) } ;
300
- unsafe { & * cls }
298
+ unsafe { ffi:: objc_registerClassPair ( cls. as_ptr ( ) . cast ( ) ) } ;
299
+ unsafe { cls. as_ref ( ) }
301
300
}
302
301
}
303
302
304
303
impl Drop for ClassDecl {
305
304
fn drop ( & mut self ) {
306
- unsafe { ffi:: objc_disposeClassPair ( self . cls as _ ) }
305
+ unsafe { ffi:: objc_disposeClassPair ( self . as_ptr ( ) ) }
307
306
}
308
307
}
309
308
310
309
/// A type for declaring a new protocol and adding new methods to it
311
310
/// before registering it.
312
311
#[ derive( Debug ) ]
313
312
pub struct ProtocolDecl {
314
- proto : * mut Protocol ,
313
+ proto : NonNull < Protocol > ,
315
314
}
316
315
317
316
// SAFETY: Similar to ClassDecl
318
317
unsafe impl Send for ProtocolDecl { }
319
318
unsafe impl Sync for ProtocolDecl { }
320
319
321
320
impl ProtocolDecl {
321
+ fn as_ptr ( & self ) -> * mut ffi:: objc_protocol {
322
+ self . proto . as_ptr ( ) . cast ( )
323
+ }
324
+
322
325
/// Constructs a [`ProtocolDecl`] with the given name.
323
326
///
324
327
/// Returns [`None`] if the protocol couldn't be allocated.
325
- pub fn new ( name : & str ) -> Option < ProtocolDecl > {
328
+ pub fn new ( name : & str ) -> Option < Self > {
326
329
let c_name = CString :: new ( name) . unwrap ( ) ;
327
330
let proto = unsafe { ffi:: objc_allocateProtocol ( c_name. as_ptr ( ) ) } as * mut Protocol ;
328
- if proto. is_null ( ) {
329
- None
330
- } else {
331
- Some ( ProtocolDecl { proto } )
332
- }
331
+ NonNull :: new ( proto) . map ( |proto| Self { proto } )
333
332
}
334
333
335
334
fn add_method_description_common < Args , Ret > (
@@ -353,7 +352,7 @@ impl ProtocolDecl {
353
352
let types = method_type_encoding ( & Ret :: ENCODING , encs) ;
354
353
unsafe {
355
354
ffi:: protocol_addMethodDescription (
356
- self . proto as _ ,
355
+ self . as_ptr ( ) ,
357
356
sel. as_ptr ( ) as _ ,
358
357
types. as_ptr ( ) ,
359
358
Bool :: new ( is_required) . as_raw ( ) ,
@@ -383,16 +382,16 @@ impl ProtocolDecl {
383
382
/// Adds a requirement on another protocol.
384
383
pub fn add_protocol ( & mut self , proto : & Protocol ) {
385
384
unsafe {
386
- ffi:: protocol_addProtocol ( self . proto as _ , proto. as_ptr ( ) ) ;
385
+ ffi:: protocol_addProtocol ( self . as_ptr ( ) , proto. as_ptr ( ) ) ;
387
386
}
388
387
}
389
388
390
389
/// Registers the [`ProtocolDecl`], consuming it and returning a reference
391
390
/// to the newly registered [`Protocol`].
392
391
pub fn register ( self ) -> & ' static Protocol {
393
392
unsafe {
394
- ffi:: objc_registerProtocol ( self . proto as _ ) ;
395
- & * self . proto
393
+ ffi:: objc_registerProtocol ( self . as_ptr ( ) ) ;
394
+ self . proto . as_ref ( )
396
395
}
397
396
}
398
397
}
0 commit comments