@@ -239,7 +239,7 @@ pub fn throw(exception: Retained<Exception>) -> ! {
239239}
240240
241241#[ cfg( feature = "exception" ) ]
242- unsafe fn try_no_ret < F : FnOnce ( ) > ( closure : F ) -> Result < ( ) , Option < Retained < Exception > > > {
242+ fn try_no_ret < F : FnOnce ( ) > ( closure : F ) -> Result < ( ) , Option < Retained < Exception > > > {
243243 let f = {
244244 extern "C-unwind" fn try_objc_execute_closure < F > ( closure : & mut Option < F > )
245245 where
@@ -291,8 +291,9 @@ unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), Option<Retained<Exce
291291/// if one is thrown.
292292///
293293/// This is the Objective-C equivalent of Rust's [`catch_unwind`].
294- /// Accordingly, if your Rust code is compiled with `panic=abort` this cannot
295- /// catch the exception.
294+ /// Accordingly, if your Rust code is compiled with `panic=abort`, or your
295+ /// Objective-C code with `-fno-objc-exceptions`, this cannot catch the
296+ /// exception.
296297///
297298/// [`catch_unwind`]: std::panic::catch_unwind
298299///
@@ -309,20 +310,26 @@ unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), Option<Retained<Exce
309310/// situations.
310311///
311312///
312- /// # Safety
313+ /// # Panics
313314///
314- /// The given closure must not panic (e.g. normal Rust unwinding into this
315- /// causes undefined behaviour).
315+ /// This panics if the given closure panics.
316+ ///
317+ /// That is, it completely ignores Rust unwinding and simply lets that pass
318+ /// through unchanged.
319+ ///
320+ /// It may also not catch all Objective-C exceptions (such as exceptions
321+ /// thrown when handling the memory management of the exception). These are
322+ /// mostly theoretical, and should only happen in utmost exceptional cases.
316323#[ cfg( feature = "exception" ) ]
317- pub unsafe fn catch < R > (
324+ pub fn catch < R > (
318325 closure : impl FnOnce ( ) -> R + UnwindSafe ,
319326) -> Result < R , Option < Retained < Exception > > > {
320327 let mut value = None ;
321328 let value_ref = & mut value;
322329 let closure = move || {
323330 * value_ref = Some ( closure ( ) ) ;
324331 } ;
325- let result = unsafe { try_no_ret ( closure) } ;
332+ let result = try_no_ret ( closure) ;
326333 // If the try succeeded, value was set so it's safe to unwrap
327334 result. map ( |( ) | value. unwrap_or_else ( || unreachable ! ( ) ) )
328335}
@@ -341,12 +348,10 @@ mod tests {
341348 #[ test]
342349 fn test_catch ( ) {
343350 let mut s = "Hello" . to_string ( ) ;
344- let result = unsafe {
345- catch ( move || {
346- s. push_str ( ", World!" ) ;
347- s
348- } )
349- } ;
351+ let result = catch ( move || {
352+ s. push_str ( ", World!" ) ;
353+ s
354+ } ) ;
350355 assert_eq ! ( result. unwrap( ) , "Hello, World!" ) ;
351356 }
352357
@@ -357,14 +362,12 @@ mod tests {
357362 ) ]
358363 fn test_catch_null ( ) {
359364 let s = "Hello" . to_string ( ) ;
360- let result = unsafe {
361- catch ( move || {
362- if !s. is_empty ( ) {
363- ffi:: objc_exception_throw ( ptr:: null_mut ( ) )
364- }
365- s. len ( )
366- } )
367- } ;
365+ let result = catch ( move || {
366+ if !s. is_empty ( ) {
367+ unsafe { ffi:: objc_exception_throw ( ptr:: null_mut ( ) ) }
368+ }
369+ s. len ( )
370+ } ) ;
368371 assert ! ( result. unwrap_err( ) . is_none( ) ) ;
369372 }
370373
@@ -376,11 +379,9 @@ mod tests {
376379 fn test_catch_unknown_selector ( ) {
377380 let obj = AssertUnwindSafe ( NSObject :: new ( ) ) ;
378381 let ptr = Retained :: as_ptr ( & obj) ;
379- let result = unsafe {
380- catch ( || {
381- let _: Retained < NSObject > = msg_send_id ! [ & * obj, copy] ;
382- } )
383- } ;
382+ let result = catch ( || {
383+ let _: Retained < NSObject > = unsafe { msg_send_id ! [ & * obj, copy] } ;
384+ } ) ;
384385 let err = result. unwrap_err ( ) . unwrap ( ) ;
385386
386387 assert_eq ! (
@@ -397,7 +398,7 @@ mod tests {
397398 let obj: Retained < Exception > = unsafe { Retained :: cast_unchecked ( obj) } ;
398399 let ptr: * const Exception = & * obj;
399400
400- let result = unsafe { catch ( || throw ( obj) ) } ;
401+ let result = catch ( || throw ( obj) ) ;
401402 let obj = result. unwrap_err ( ) . unwrap ( ) ;
402403
403404 assert_eq ! ( format!( "{obj:?}" ) , format!( "exception <NSObject: {ptr:p}>" ) ) ;
@@ -422,6 +423,6 @@ mod tests {
422423 ignore = "panic won't start on 32-bit / w. fragile runtime, it'll just abort, since the runtime uses setjmp/longjump unwinding"
423424 ) ]
424425 fn does_not_catch_panic ( ) {
425- let _ = unsafe { catch ( || panic ! ( "test" ) ) } ;
426+ let _ = catch ( || panic ! ( "test" ) ) ;
426427 }
427428}
0 commit comments