@@ -676,15 +676,8 @@ impl FnReturn {
676676
677677 pub fn type_tokens ( & self ) -> TokenStream {
678678 match & self . type_ {
679- Some ( RustTy :: EngineClass { tokens, .. } ) => {
680- quote ! { Option <#tokens> }
681- }
682- Some ( ty) => {
683- quote ! { #ty }
684- }
685- _ => {
686- quote ! { ( ) }
687- }
679+ Some ( ty) => ty. to_token_stream ( ) ,
680+ _ => quote ! { ( ) } ,
688681 }
689682 }
690683
@@ -726,6 +719,7 @@ pub struct GodotTy {
726719pub enum RustTy {
727720 /// `bool`, `Vector3i`, `Array`, `GString`
728721 BuiltinIdent { ty : Ident , arg_passing : ArgPassing } ,
722+
729723 /// Pointers declared in `gdextension_interface` such as `sys::GDExtensionInitializationFunction`
730724 /// used as parameters in some APIs.
731725 SysPointerType { tokens : TokenStream } ,
@@ -761,16 +755,19 @@ pub enum RustTy {
761755
762756 /// `Gd<Node>`
763757 EngineClass {
764- /// Tokens with full `Gd<T>` (e.g. used in return type position) .
765- tokens : TokenStream ,
758+ /// Tokens with full `Gd<T>`, never `Option<Gd<T>>` .
759+ gd_tokens : TokenStream ,
766760
767- /// Signature declaration with `impl AsArg<Gd<T>>`.
761+ /// Signature declaration with `impl AsArg<Gd<T>>` or `impl AsArg<Option<Gd<T>>>` .
768762 impl_as_object_arg : TokenStream ,
769763
770- /// only inner `T`
771- #[ allow( dead_code) ]
772- // only read in minimal config + RustTy::default_extender_field_decl()
764+ /// Only inner `Node`.
773765 inner_class : Ident ,
766+
767+ /// Whether this object parameter/return is nullable in the GDExtension API.
768+ ///
769+ /// Defaults to true (nullable). Only false when meta="required".
770+ is_nullable : bool ,
774771 } ,
775772
776773 /// Receiver type of default parameters extender constructor.
@@ -789,9 +786,20 @@ impl RustTy {
789786
790787 pub fn return_decl ( & self ) -> TokenStream {
791788 match self {
792- Self :: EngineClass { tokens, .. } => quote ! { -> Option <#tokens> } ,
793789 Self :: GenericArray => quote ! { -> Array <Ret > } ,
794- other => quote ! { -> #other } ,
790+ _ => quote ! { -> #self } ,
791+ }
792+ }
793+
794+ /// Returns tokens without `Option<T>` wrapper, even for nullable engine classes.
795+ ///
796+ /// For `EngineClass`, always returns `Gd<T>` regardless of nullability. For other types, behaves the same as `ToTokens`.
797+ // TODO(v0.5): only used for signal params, which is a bug. Those should conservatively be Option<Gd<T>> as well.
798+ // Might also be useful to directly extract inner `gd_tokens` field.
799+ pub fn tokens_non_null ( & self ) -> TokenStream {
800+ match self {
801+ Self :: EngineClass { gd_tokens, .. } => gd_tokens. clone ( ) ,
802+ other => other. to_token_stream ( ) ,
795803 }
796804 }
797805
@@ -849,7 +857,18 @@ impl ToTokens for RustTy {
849857 } => quote ! { * mut #inner } . to_tokens ( tokens) ,
850858 RustTy :: EngineArray { tokens : path, .. } => path. to_tokens ( tokens) ,
851859 RustTy :: EngineEnum { tokens : path, .. } => path. to_tokens ( tokens) ,
852- RustTy :: EngineClass { tokens : path, .. } => path. to_tokens ( tokens) ,
860+ RustTy :: EngineClass {
861+ is_nullable,
862+ gd_tokens : path,
863+ ..
864+ } => {
865+ // Return nullable-aware type: Option<Gd<T>> if nullable, else Gd<T>.
866+ if * is_nullable {
867+ quote ! { Option <#path> } . to_tokens ( tokens)
868+ } else {
869+ path. to_tokens ( tokens)
870+ }
871+ }
853872 RustTy :: ExtenderReceiver { tokens : path } => path. to_tokens ( tokens) ,
854873 RustTy :: GenericArray => quote ! { Array <Ret > } . to_tokens ( tokens) ,
855874 RustTy :: SysPointerType { tokens : path } => path. to_tokens ( tokens) ,
0 commit comments