Skip to content

feat(syntax,semantic,lowering): support tuple struct syntax (struct Foo(T1, T2))#9885

Draft
orizi wants to merge 1 commit intoorizi/04-26-feat_semantic_support_tuple_member_access_via_v.0_syntax_7608_from
orizi/04-29-feat_syntax_semantic_lowering_support_tuple_struct_syntax_struct_foo_t1_t2_
Draft

feat(syntax,semantic,lowering): support tuple struct syntax (struct Foo(T1, T2))#9885
orizi wants to merge 1 commit intoorizi/04-26-feat_semantic_support_tuple_member_access_via_v.0_syntax_7608_from
orizi/04-29-feat_syntax_semantic_lowering_support_tuple_struct_syntax_struct_foo_t1_t2_

Conversation

@orizi
Copy link
Copy Markdown
Collaborator

@orizi orizi commented Apr 29, 2026

Summary

Adds support for tuple struct syntax in Cairo, allowing structs to be defined with positional, unnamed fields using parentheses: struct Foo(pub u32, u64). This introduces a new StructBody enum in the AST with two variants — StructBodyBraces (the existing { field: Type } form) and StructBodyParens (the new (Type, Type) form) — replacing the flat lbrace/members/rbrace fields on ItemStruct.

New AST nodes StructArgMember, StructArgMemberList, StructBodyBraces, and StructBodyParens are added to the syntax spec and generated code. The parser is extended to detect a leading ( after the struct name and parse a StructArgMemberList instead of a MemberList.

On the semantic side, StructDefinitionData gains a positional_tys field (a Vec<(TypeId, Visibility)>) populated for tuple structs. Two new Salsa queries — struct_positional_types and concrete_struct_positional_types — expose these types with generic substitution applied. type_members is updated to return TupleElement-kinded members (keyed by stringified index, e.g. "0", "1") for tuple structs, enabling member access expressions like p.0.

Lowering is updated so that TupleElement access on a concrete struct type fetches positional types via concrete_struct_positional_types rather than assuming the container is always a TypeLongId::Tuple.

The MemberId::struct_id parent pointer traversal is corrected from 2 levels to 3 levels up to account for the new StructBodyBraces intermediate node.

All call sites that previously called struct_ast.members(db) directly are updated to first match on StructBody::Braces, gracefully skipping or returning early for tuple structs.


Type of change

Please check one:

  • Bug fix (fixes incorrect behavior)
  • New feature
  • Performance improvement
  • Documentation change with concrete technical impact
  • Style, wording, formatting, or typo-only change

Why is this change needed?

Cairo previously only supported braced struct syntax. Tuple structs (positional, unnamed fields) are a common pattern in Rust-like languages and are needed to support use cases where field names are unnecessary or where struct types should behave similarly to tuples with named types.


What was the behavior or documentation before?

Structs could only be declared with named fields inside braces: struct Foo { x: u32, y: u64 }. The ItemStruct AST node directly held lbrace, members, and rbrace children.


What is the behavior or documentation after?

Structs can additionally be declared with positional fields inside parentheses: struct Foo(pub u32, u64). Fields are accessed by numeric index (e.g., foo.0). The ItemStruct AST node now holds a single body child of type StructBody, which is either StructBodyBraces or StructBodyParens.


Related issue or discussion (if any)

N/A


Additional context

Parser test data snapshots (test1, test2, attrs) are updated to reflect the new StructBodyBraces wrapper node in the AST. A new unit test test_tuple_struct verifies positional type extraction, visibility, and type_members behavior for tuple structs.

@reviewable-StarkWare
Copy link
Copy Markdown

This change is Reviewable

Copy link
Copy Markdown
Collaborator Author

orizi commented Apr 29, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@orizi orizi force-pushed the orizi/04-29-feat_syntax_semantic_lowering_support_tuple_struct_syntax_struct_foo_t1_t2_ branch from 41506df to 5862e6d Compare April 29, 2026 12:23
@orizi orizi force-pushed the orizi/04-26-feat_semantic_support_tuple_member_access_via_v.0_syntax_7608_ branch from 5e73005 to 3574eae Compare April 29, 2026 12:23
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.

2 participants