Skip to content

Conversation

@ariesdevil
Copy link
Contributor

@ariesdevil ariesdevil commented Dec 27, 2025

Why?

When computing struct version hash (fingerprint) for cross-language compatibility, Java and C++ treat enum fields as nullable=true by default (since Java enums are reference types that can be null). However, Rust's proc-macro cannot determine at compile time whether a field type is an enum, causing fingerprint mismatch between Rust and Java/C++.

For example, a struct like:

struct Message {
    state: MyEnum,  // Java: nullable=true, Rust (before): nullable=false
    name: String,
}

Would produce different version hashes in Rust vs Java/C++, breaking cross-language schema compatibility.

What does this PR do?

This PR aligns Rust's struct fingerprint computation with Java/C++ behavior:

  1. Add runtime enum detection for fingerprint computation

    • Create gen_struct_version_hash_ts() that generates code to compute fingerprint at runtime
    • For user-defined types (TypeId::UNKNOWN at macro time), call fory_static_type_id() to detect enums
    • For known primitive types, use compile-time constants to avoid unnecessary trait bounds
  2. Add helper function is_enum_type_id()

    • Checks if TypeId is ENUM, NAMED_ENUM, or UNION (Union-compatible Rust enums)
  3. Fix Union-compatible enum handling

    • Add xlang parameter to fory_actual_type_id() for proper TypeId selection
    • Fix enum variant meta registration to handle Union-compatible enums
    • Fix field_need_write_type_info() to handle UNION TypeId

Now Rust computes the same fingerprint as Java/C++.

Related issues

Does this PR introduce any user-facing change?

  • Does this PR introduce any public API change?
  • Does this PR introduce any binary protocol compatibility change?
    Note: This changes the struct version hash computation for structs containing enum fields. The new hash will match Java/C++, but may differ from previous Rust versions. This is intentional for cross-language compatibility.

Benchmark

Others

It's really hard to determine this bug 😭...

@ariesdevil ariesdevil force-pushed the feat/xlang-union-rust-java branch from 19cada8 to b11e307 Compare December 27, 2025 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant