@@ -721,14 +721,14 @@ fn namespace(resolve: &Resolve, owner: &TypeOwner, guest_export: bool, opts: &Op
721721 result. push ( String :: from ( "exports" ) ) ;
722722 }
723723 match owner {
724- TypeOwner :: World ( w) => result. push ( resolve. worlds [ * w] . name . to_snake_case ( ) ) ,
724+ TypeOwner :: World ( w) => result. push ( to_c_ident ( & resolve. worlds [ * w] . name ) ) ,
725725 TypeOwner :: Interface ( i) => {
726726 let iface = & resolve. interfaces [ * i] ;
727727 let pkg = & resolve. packages [ iface. package . unwrap ( ) ] ;
728- result. push ( pkg. name . namespace . to_snake_case ( ) ) ;
729- result. push ( pkg. name . name . to_snake_case ( ) ) ;
728+ result. push ( to_c_ident ( & pkg. name . namespace ) ) ;
729+ result. push ( to_c_ident ( & pkg. name . name ) ) ;
730730 if let Some ( name) = & iface. name {
731- result. push ( name . to_snake_case ( ) ) ;
731+ result. push ( to_c_ident ( name ) ) ;
732732 }
733733 }
734734 TypeOwner :: None => ( ) ,
@@ -797,8 +797,23 @@ struct CppInterfaceGenerator<'a> {
797797
798798impl CppInterfaceGenerator < ' _ > {
799799 fn types ( & mut self , iface : InterfaceId ) {
800- let iface = & self . resolve ( ) . interfaces [ iface] ;
801- for ( name, id) in iface. types . iter ( ) {
800+ let iface_data = & self . resolve ( ) . interfaces [ iface] ;
801+
802+ // First pass: emit forward declarations for all resources
803+ // This ensures resources can reference each other in method signatures
804+ for ( name, id) in iface_data. types . iter ( ) {
805+ let ty = & self . resolve ( ) . types [ * id] ;
806+ if matches ! ( & ty. kind, TypeDefKind :: Resource ) {
807+ let pascal = name. to_upper_camel_case ( ) ;
808+ let guest_import = self . gen . imported_interfaces . contains ( & iface) ;
809+ let namespc = namespace ( self . resolve , & ty. owner , !guest_import, & self . gen . opts ) ;
810+ self . gen . h_src . change_namespace ( & namespc) ;
811+ uwriteln ! ( self . gen . h_src. src, "class {pascal};" ) ;
812+ }
813+ }
814+
815+ // Second pass: emit full type definitions
816+ for ( name, id) in iface_data. types . iter ( ) {
802817 self . define_type ( name, * id) ;
803818 }
804819 }
@@ -1055,7 +1070,7 @@ impl CppInterfaceGenerator<'_> {
10551070 ""
10561071 } ;
10571072 res. arguments . push ( (
1058- name . to_snake_case ( ) ,
1073+ to_c_ident ( name ) ,
10591074 self . type_name ( param, & res. namespace , Flavor :: Argument ( abi_variant) ) + is_pointer,
10601075 ) ) ;
10611076 }
@@ -1662,7 +1677,7 @@ impl CppInterfaceGenerator<'_> {
16621677 uwriteln ! ( self . gen . h_src. src, "struct {pascal} {{" ) ;
16631678 for field in record. fields . iter ( ) {
16641679 let typename = self . type_name ( & field. ty , namespc, flavor) ;
1665- let fname = field. name . to_snake_case ( ) ;
1680+ let fname = to_c_ident ( & field. name ) ;
16661681 uwriteln ! ( self . gen . h_src. src, "{typename} {fname};" ) ;
16671682 }
16681683 uwriteln ! ( self . gen . h_src. src, "}};" ) ;
@@ -1703,7 +1718,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
17031718 for field in record. fields . iter ( ) {
17041719 Self :: docs ( & mut self . gen . h_src . src , & field. docs ) ;
17051720 let typename = self . type_name ( & field. ty , & namespc, Flavor :: InStruct ) ;
1706- let fname = field. name . to_snake_case ( ) ;
1721+ let fname = to_c_ident ( & field. name ) ;
17071722 uwriteln ! ( self . gen . h_src. src, "{typename} {fname};" ) ;
17081723 }
17091724 uwriteln ! ( self . gen . h_src. src, "}};" ) ;
@@ -1722,7 +1737,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
17221737 let guest_import = self . gen . imported_interfaces . contains ( & intf) ;
17231738 let definition = !( guest_import) ;
17241739 let store = self . gen . start_new_file ( Some ( definition) ) ;
1725- let mut world_name = self . gen . world . to_snake_case ( ) ;
1740+ let mut world_name = to_c_ident ( & self . gen . world ) ;
17261741 world_name. push_str ( "::" ) ;
17271742 let namespc = namespace ( self . resolve , & type_. owner , !guest_import, & self . gen . opts ) ;
17281743 let pascal = name. to_upper_camel_case ( ) ;
@@ -1884,7 +1899,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
18841899 uwriteln ! ( self . gen . h_src. src, "k_None = 0," ) ;
18851900 for ( n, field) in flags. flags . iter ( ) . enumerate ( ) {
18861901 Self :: docs ( & mut self . gen . h_src . src , & field. docs ) ;
1887- let fname = field. name . to_pascal_case ( ) ;
1902+ let fname = to_c_ident ( & field. name ) . to_pascal_case ( ) ;
18881903 uwriteln ! ( self . gen . h_src. src, "k{fname} = (1ULL<<{n})," ) ;
18891904 }
18901905 uwriteln ! ( self . gen . h_src. src, "}};" ) ;
@@ -1926,7 +1941,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
19261941 let mut all_types = String :: new ( ) ;
19271942 for case in variant. cases . iter ( ) {
19281943 Self :: docs ( & mut self . gen . h_src . src , & case. docs ) ;
1929- let case_pascal = case. name . to_pascal_case ( ) ;
1944+ let case_pascal = to_c_ident ( & case. name ) . to_pascal_case ( ) ;
19301945 if !all_types. is_empty ( ) {
19311946 all_types += ", " ;
19321947 }
@@ -1985,7 +2000,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
19852000 uwriteln ! (
19862001 self . gen . h_src. src,
19872002 " k{} = {i}," ,
1988- case. name. to_pascal_case( ) ,
2003+ to_c_ident ( & case. name) . to_pascal_case( ) ,
19892004 ) ;
19902005 }
19912006 uwriteln ! ( self . gen . h_src. src, "}};\n " ) ;
@@ -2655,7 +2670,8 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
26552670 uwriteln ! ( self . src, "case {}: {{" , i) ;
26562671 if let Some ( ty) = case. ty . as_ref ( ) {
26572672 let ty = self . gen . type_name ( ty, & self . namespace , Flavor :: InStruct ) ;
2658- let case = format ! ( "{elem_ns}::{}" , case. name. to_pascal_case( ) ) ;
2673+ let case =
2674+ format ! ( "{elem_ns}::{}" , to_c_ident( & case. name) . to_pascal_case( ) ) ;
26592675 uwriteln ! (
26602676 self . src,
26612677 "{} &{} = std::get<{case}>({}.variants).value;" ,
@@ -2686,24 +2702,26 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
26862702 let resultno = self . tmp ( ) ;
26872703 let result = format ! ( "variant{resultno}" ) ;
26882704
2689- uwriteln ! ( self . src, "{ty} {result};" ) ;
2690-
26912705 let op0 = & operands[ 0 ] ;
26922706
2707+ // Use std::optional to avoid default constructor issues
2708+ self . gen . gen . dependencies . needs_optional = true ;
2709+ uwriteln ! ( self . src, "std::optional<{ty}> {result}_opt;" ) ;
26932710 uwriteln ! ( self . src, "switch ({op0}) {{" ) ;
26942711 for ( i, ( case, ( block, block_results) ) ) in
26952712 variant. cases . iter ( ) . zip ( blocks) . enumerate ( )
26962713 {
2697- let tp = case. name . clone ( ) . to_pascal_case ( ) ;
2714+ let tp = to_c_ident ( & case. name ) . to_pascal_case ( ) ;
26982715 uwriteln ! ( self . src, "case {i}: {{ {block}" ) ;
26992716 uwriteln ! (
27002717 self . src,
2701- "{result}.variants = {ty}::{tp}{{{}}};" ,
2718+ "{result}_opt = {ty}{{{{{ty} ::{tp}{{{}}}} }}};" ,
27022719 move_if_necessary( & block_results. first( ) . cloned( ) . unwrap_or_default( ) )
27032720 ) ;
27042721 uwriteln ! ( self . src, "}} break;" ) ;
27052722 }
27062723 uwriteln ! ( self . src, "}}" ) ;
2724+ uwriteln ! ( self . src, "{ty} {result} = std::move(*{result}_opt);" ) ;
27072725
27082726 results. push ( result) ;
27092727 }
@@ -2874,21 +2892,24 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
28742892
28752893 let tmp = self . tmp ( ) ;
28762894 let resultname = self . tempname ( "result" , tmp) ;
2895+ // Use std::optional to avoid default constructor issues with std::expected
2896+ self . gen . gen . dependencies . needs_optional = true ;
28772897 let ok_assign = if result. ok . is_some ( ) {
2878- format ! ( "{resultname}.emplace({ok_result});" )
2898+ format ! ( "{resultname}_opt .emplace({full_type}({ ok_result}) );" )
28792899 } else {
2880- String :: new ( )
2900+ format ! ( "{resultname}_opt.emplace({full_type}());" )
28812901 } ;
28822902 uwriteln ! (
28832903 self . src,
2884- "{full_type} {resultname};
2904+ "std::optional< {full_type}> {resultname}_opt ;
28852905 if ({operand}==0) {{
28862906 {ok}
28872907 {ok_assign}
28882908 }} else {{
28892909 {err}
2890- {resultname}={err_type}{{{err_result}}};
2891- }}"
2910+ {resultname}_opt.emplace({err_type}{{{err_result}}});
2911+ }}
2912+ {full_type} {resultname} = std::move(*{resultname}_opt);"
28922913 ) ;
28932914 results. push ( resultname) ;
28942915 }
0 commit comments