@@ -39,6 +39,7 @@ use alloc::string::ToString;
3939use core:: mem;
4040use core:: mem:: ManuallyDrop ;
4141use core:: ptr;
42+ use core:: ptr:: NonNull ;
4243use std:: ffi:: CString ;
4344
4445use crate :: runtime:: { Bool , Class , Imp , Object , Protocol , Sel } ;
@@ -120,7 +121,7 @@ fn log2_align_of<T>() -> u8 {
120121/// before registering it.
121122#[ derive( Debug ) ]
122123pub struct ClassDecl {
123- cls : * mut Class ,
124+ cls : NonNull < Class > ,
124125}
125126
126127// SAFETY: The stuff that touch global state does so using locks internally.
@@ -138,23 +139,23 @@ unsafe impl Send for ClassDecl {}
138139unsafe impl Sync for ClassDecl { }
139140
140141impl 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 > {
142147 let name = CString :: new ( name) . unwrap ( ) ;
143148 let super_ptr = superclass. map_or ( ptr:: null ( ) , |c| c) as _ ;
144149 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 } )
150151 }
151152
152153 /// Constructs a [`ClassDecl`] with the given name and superclass.
153154 ///
154155 /// Returns [`None`] if the class couldn't be allocated, or a class with
155156 /// 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) )
158159 }
159160
160161 /// Constructs a [`ClassDecl`] declaring a new root class with the given
@@ -171,12 +172,10 @@ impl ClassDecl {
171172 /// the entire `NSObject` protocol is implemented.
172173 /// Functionality it expects, like implementations of `-retain` and
173174 /// `-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 ) ;
176177 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) } ;
180179 }
181180 decl
182181 }
@@ -209,7 +208,7 @@ impl ClassDecl {
209208 let types = method_type_encoding ( & F :: Ret :: ENCODING , encs) ;
210209 let success = Bool :: from_raw ( unsafe {
211210 ffi:: class_addMethod (
212- self . cls as _ ,
211+ self . as_ptr ( ) ,
213212 sel. as_ptr ( ) as _ ,
214213 Some ( func. imp ( ) ) ,
215214 types. as_ptr ( ) ,
@@ -244,7 +243,7 @@ impl ClassDecl {
244243 ) ;
245244
246245 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 _ ;
248247 let success = Bool :: from_raw ( unsafe {
249248 ffi:: class_addMethod (
250249 metaclass,
@@ -268,7 +267,7 @@ impl ClassDecl {
268267 let align = log2_align_of :: < T > ( ) ;
269268 let success = Bool :: from_raw ( unsafe {
270269 ffi:: class_addIvar (
271- self . cls as _ ,
270+ self . as_ptr ( ) ,
272271 c_name. as_ptr ( ) ,
273272 size,
274273 align,
@@ -284,7 +283,7 @@ impl ClassDecl {
284283 ///
285284 /// If the protocol wasn't successfully added.
286285 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 ( ) ) } ;
288287 let success = Bool :: from_raw ( success) . as_bool ( ) ;
289288 assert ! ( success, "Failed to add protocol {:?}" , proto) ;
290289 }
@@ -296,40 +295,40 @@ impl ClassDecl {
296295 pub fn register ( self ) -> & ' static Class {
297296 // Forget self, otherwise the class will be disposed in drop
298297 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 ( ) }
301300 }
302301}
303302
304303impl Drop for ClassDecl {
305304 fn drop ( & mut self ) {
306- unsafe { ffi:: objc_disposeClassPair ( self . cls as _ ) }
305+ unsafe { ffi:: objc_disposeClassPair ( self . as_ptr ( ) ) }
307306 }
308307}
309308
310309/// A type for declaring a new protocol and adding new methods to it
311310/// before registering it.
312311#[ derive( Debug ) ]
313312pub struct ProtocolDecl {
314- proto : * mut Protocol ,
313+ proto : NonNull < Protocol > ,
315314}
316315
317316// SAFETY: Similar to ClassDecl
318317unsafe impl Send for ProtocolDecl { }
319318unsafe impl Sync for ProtocolDecl { }
320319
321320impl ProtocolDecl {
321+ fn as_ptr ( & self ) -> * mut ffi:: objc_protocol {
322+ self . proto . as_ptr ( ) . cast ( )
323+ }
324+
322325 /// Constructs a [`ProtocolDecl`] with the given name.
323326 ///
324327 /// 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 > {
326329 let c_name = CString :: new ( name) . unwrap ( ) ;
327330 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 } )
333332 }
334333
335334 fn add_method_description_common < Args , Ret > (
@@ -353,7 +352,7 @@ impl ProtocolDecl {
353352 let types = method_type_encoding ( & Ret :: ENCODING , encs) ;
354353 unsafe {
355354 ffi:: protocol_addMethodDescription (
356- self . proto as _ ,
355+ self . as_ptr ( ) ,
357356 sel. as_ptr ( ) as _ ,
358357 types. as_ptr ( ) ,
359358 Bool :: new ( is_required) . as_raw ( ) ,
@@ -383,16 +382,16 @@ impl ProtocolDecl {
383382 /// Adds a requirement on another protocol.
384383 pub fn add_protocol ( & mut self , proto : & Protocol ) {
385384 unsafe {
386- ffi:: protocol_addProtocol ( self . proto as _ , proto. as_ptr ( ) ) ;
385+ ffi:: protocol_addProtocol ( self . as_ptr ( ) , proto. as_ptr ( ) ) ;
387386 }
388387 }
389388
390389 /// Registers the [`ProtocolDecl`], consuming it and returning a reference
391390 /// to the newly registered [`Protocol`].
392391 pub fn register ( self ) -> & ' static Protocol {
393392 unsafe {
394- ffi:: objc_registerProtocol ( self . proto as _ ) ;
395- & * self . proto
393+ ffi:: objc_registerProtocol ( self . as_ptr ( ) ) ;
394+ self . proto . as_ref ( )
396395 }
397396 }
398397}
0 commit comments