You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
➖ Flaky Test Retry: All CI checks passing; no test failures detected
➖ Rule Quality Standards: No Gitar rule markdown files modified; only Rust code files changed
Code Review
Critical bugs found in TypeScript enum generation - conflates default externally-tagged enums with untagged enums.
The PR contains two commits: a version bump (benign) and a fix for "untagged support". However, the fix introduces critical bugs:
Primary Issues:
Incorrect type generation for default enums (Critical): The fix assumes empty tag_key means "untagged enum", but it actually means "no explicit serde(tag) attribute". Default Rust enums are externally-tagged and serialize as {"VariantName": value}, not as bare value. The generated TypeScript types will not match the actual JSON structure.
Missing #[serde(untagged)] parsing (Critical): The parser never checks for the untagged serde attribute, making it impossible to distinguish truly untagged enums from default externally-tagged enums.
Inconsistent variant handling (Critical): When tag_key is empty, Unit variants output string literals, Tuple variants output bare types, and AnonymousStruct variants output wrapped objects - all from the same enum, creating incompatible TypeScript union types.
Root Cause: The codebase conflates "no tag attribute" with "untagged enum" when these represent different serde behaviors.
Recommendations:
Add parsing for #[serde(untagged)] in parser.rs
Store untagged flag in RustEnum::Algebraic structure
Update TypeScript generator to distinguish default vs untagged enums
Add test coverage for default externally-tagged enums
Ensure all three variant types handle both cases consistently
The commit message says this "fixes" untagged support, but without proper untagged attribute parsing, the fix is based on incorrect assumptions about what empty tag_key represents.
Missing parsing of #[serde(untagged)] attribute (core/src/parser.rs) - critical
Inconsistent handling of empty tag_key between variant types (core/src/language/typescript.rs:293) - critical
View All Findings
Bugs
Incorrect TypeScript generation for default (externally tagged) enums
Location: core/src/language/typescript.rs:326-329
Severity: critical
Confidence: 95%
Issue: The fix changes tuple variant output to | InnerType when tag_key is empty. However, an empty tag_key doesn't necessarily mean the enum is untagged - it could be a default Rust enum (externally tagged).
Root Cause: The parser doesn't check for #[serde(untagged)] attribute. When no serde tag attribute exists, tag_key defaults to empty string, but this is ambiguous:
Default enum without serde attributes → serializes as { "VariantName": value } → TypeScript should be { "VariantName": Type }
Enum with #[serde(untagged)] → serializes as just value → TypeScript should be Type
Impact: This breaks TypeScript type generation for all default Rust enums with tuple variants. Generated types won't match actual JSON structure.
Example:
enumMyEnum{Variant(String)}// No serde attribute
Current output: type MyEnum = | string (WRONG)
Expected output: type MyEnum = | { "Variant": string } (CORRECT)
Fix Needed:
Parse #[serde(untagged)] attribute in parser.rs
Store this info in RustEnum structure
Only emit | InnerType when truly untagged; otherwise emit | { "VariantName": InnerType }
Missing parsing of #[serde(untagged)] attribute
Location: core/src/parser.rs
Severity: critical
Confidence: 95%
Issue: The parser checks for #[serde(tag = "...")] and #[serde(content = "...")] but doesn't check for #[serde(untagged)]. This makes it impossible to distinguish between:
Untagged enums: #[serde(untagged)] enum E { A(String) } → serializes as "value"
Default externally-tagged enums: enum E { A(String) } → serializes as { "A": "value" }
Current Behavior: Both cases result in tag_key = "", making them indistinguishable in code generation.
Impact: Language generators cannot correctly generate types for untagged enums vs default enums. The TypeScript generator currently assumes empty tag_key means untagged, which is incorrect.
Fix Needed:
Add function get_untagged(attrs: &[syn::Attribute]) -> bool to check for #[serde(untagged)]
Store this boolean in RustEnum::Algebraic struct (requires updating rust_types.rs)
Update all language generators to use this flag correctly
Impact: For the same enum type (empty tag_key), different variant types generate incompatible TypeScript types. This creates confusing and potentially broken type definitions.
These three variants should all follow the same tagging convention (all with or all without variant names).
Fix Needed: All three variant types must handle empty tag_key consistently. Since this likely represents default externally-tagged enums, all should include the variant name wrapper.
Code Quality
Comment doesn't match actual behavior
Location: core/src/language/typescript.rs:327-327
Severity: minor
Confidence: 100%
Issue: The comment says "Untagged: just output the inner type directly" but empty tag_key doesn't necessarily indicate an untagged enum (see other findings).
Fix: Update comment to accurately reflect the ambiguity, or better yet, fix the underlying bug so that this truly only triggers for untagged enums.
Suggested comment: "Empty tag_key: output inner type (NOTE: this is incorrect for default externally-tagged enums - see #ISSUE)"
Auto-apply suggestions - Allow Gitar to commit updates to this branch
Was this helpful? React with 👍 / 👎 | This comment will update automatically (Docs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Test Plan
Revert Plan
Summary by Gitar
AlgebraicEnumnow output direct types instead of wrapped objects incore/src/language/typescript.rs:324-3291.13.3-gitaracrosscli/Cargo.toml,core/Cargo.toml, andCargo.lock