@@ -344,20 +344,19 @@ pub(crate) fn generate_methods(
344
344
let icall_name = method_sig. function_name ( ) ;
345
345
let icall = format_ident ! ( "{}" , icall_name) ;
346
346
347
- icalls. insert ( icall_name. clone ( ) , method_sig) ;
348
-
349
- let rusty_name = rust_safe_name ( rusty_method_name) ;
350
-
351
347
let maybe_unsafe: TokenStream ;
352
348
let maybe_unsafe_reason: & str ;
353
- if UNSAFE_OBJECT_METHODS . contains ( & ( & class. name , method_name) ) {
349
+ if let Some ( unsafe_reason ) = unsafe_reason ( class, method_name, & method_sig ) {
354
350
maybe_unsafe = quote ! { unsafe } ;
355
- maybe_unsafe_reason = "\n # Safety\n This function bypasses Rust's static type checks \
356
- (aliasing, thread boundaries, calls to free(), ...).";
351
+ maybe_unsafe_reason = unsafe_reason;
357
352
} else {
358
353
maybe_unsafe = TokenStream :: default ( ) ;
359
354
maybe_unsafe_reason = "" ;
360
- } ;
355
+ }
356
+
357
+ icalls. insert ( icall_name. clone ( ) , method_sig) ;
358
+
359
+ let rusty_name = rust_safe_name ( rusty_method_name) ;
361
360
362
361
let method_bind_fetch = {
363
362
let method_table = format_ident ! ( "{}MethodTable" , class. name) ;
@@ -394,6 +393,27 @@ pub(crate) fn generate_methods(
394
393
result
395
394
}
396
395
396
+ /// Returns a message as to why this method would be unsafe; or None if the method is safe
397
+ fn unsafe_reason (
398
+ class : & GodotClass ,
399
+ method_name : & str ,
400
+ method_sig : & MethodSig ,
401
+ ) -> Option < & ' static str > {
402
+ if UNSAFE_OBJECT_METHODS . contains ( & ( & class. name , method_name) ) {
403
+ Some (
404
+ "\n # Safety\
405
+ \n This function bypasses Rust's static type checks (aliasing, thread boundaries, calls to free(), ...).",
406
+ )
407
+ } else if method_sig. arguments . contains ( & Ty :: Rid ) {
408
+ Some (
409
+ "\n # Safety\
410
+ \n This function has parameters of type `Rid` (resource ID). \
411
+ RIDs are untyped and interpreted as raw pointers by the engine, so passing an incorrect RID can cause UB.")
412
+ } else {
413
+ None
414
+ }
415
+ }
416
+
397
417
fn ret_recover ( ty : & Ty , icall_ty : IcallType ) -> TokenStream {
398
418
match icall_ty {
399
419
IcallType :: Ptr => ty. to_return_post ( ) ,
0 commit comments