The GitHub Actions job "Fory CI" on fory.git/main has succeeded. Run started by GitHub user chaokunyang (triggered by chaokunyang).
Head commit for run: 20f51a1d2992c6c877f28d360dcd95de43128a7e / Peiyang He <[email protected]> fix(compiler): alias C++ union case types in metadata macros (#3814) ## Why? The C++ compiler can emit union metadata macros that fail to compile when a union case payload type contains a C++ template comma, e.g. `std::unordered_map<K, V>`. There are two affected paths: - `FORY_UNION(...)` for unions with at most 16 cases. - `FORY_UNION_IDS(...)` plus `FORY_UNION_CASE(...)` for larger unions. Example IDL: ``` package probe.cpp_macro_fory_union; union SmallChoice { map<string, any> by_name = 1; string name = 2; } ``` Generated C++ code: ```c++ FORY_UNION(probe::cpp_macro_fory_union::SmallChoice, (by_name, std::unordered_map<std::string, std::any>, fory::F(1).map(fory::T::string(), fory::FieldNodeSpec{})), (name, std::string, fory::F(2)) ); ``` Observed compile error: ```text /home/hpy/fory/cpp/fory/serialization/union_serializer.h:1203:18: error: 'FORY_UNION_CASE_META_fory' has not been declared /tmp/fory_cpp_macro_pr_wql7zo9p/generated/probe_cpp_macro_fory_union.h:140:4: error: 'by_name' was not declared in this scope /tmp/fory_cpp_macro_pr_wql7zo9p/generated/probe_cpp_macro_fory_union.h:140:54: error: expected primary-expression before ',' token /home/hpy/fory/cpp/fory/serialization/union_serializer.h:1192:18: error: 'FORY_UNION_CASE_TYPE_fory' was not declared in this scope; did you mean 'FORY_UNION_CASE_TYPE_2'? ``` **Root cause**: The generator passed **raw** C++ type names into `FORY_UNION` case tuples. `FORY_UNION` rendered each case as `(case_name, case_type, meta)`: https://github.com/apache/fory/blob/23aa3f98ee56687c555c681a488a69d8cfbb5832/compiler/fory_compiler/generators/cpp.py#L1203-L1221 This is unsafe for template types such as `std::unordered_map<std::string, std::any>`. C++ macro preprocessing happens before the compiler understands that the comma inside `<K, V>` belongs to a template argument list. The preprocessor treats that comma as a macro argument separator. `FORY_UNION` expects each case tuple to have either two entries `(name, meta)` or three entries `(name, type, meta)`: https://github.com/apache/fory/blob/23aa3f98ee56687c555c681a488a69d8cfbb5832/cpp/fory/serialization/union_serializer.h#L1179-L1207 When the generated tuple contains: ```cpp (by_name, std::unordered_map<std::string, std::any>, meta) ``` the preprocessor sees more entries than intended because of the comma in `std::unordered_map<std::string, std::any>`. That breaks tuple-size selection and causes invalid macro names such as `FORY_UNION_CASE_META_fory` or `FORY_UNION_CASE_TYPE_fory`. ## What does this PR do? Fix this by generating a union-scoped type alias for case payload types whose rendered C++ type contains a comma, and use that alias in `FORY_UNION` and `FORY_UNION_CASE` metadata. The generated alias name is derived from the union case name using the pattern: `ForyCase` + PascalCase(case_name) + `Type`. e.g. ```cpp class SmallChoice final { public: using ForyCaseByNameType = std::unordered_map<std::string, std::any>; ... }; FORY_UNION(probe::cpp_macro_fory_union::SmallChoice, (by_name, probe::cpp_macro_fory_union::SmallChoice::ForyCaseByNameType, fory::F(1).map(...)), (name, std::string, fory::F(2)) ); ``` The macro now receives `SmallChoice::ForyCaseByNameType`, which contains no template comma and can be parsed safely by the preprocessor. Note: I will handle naming collisions universally in a new PR. ## Related issues N/A. ## AI Contribution Checklist - [X] Substantial AI assistance was used in this PR: `no` ## Does this PR introduce any user-facing change? N/A. ## Benchmark N/A. Report URL: https://github.com/apache/fory/actions/runs/28699524724 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
