Skip to content

Index Struct.new#485

Open
vinistock wants to merge 1 commit intomainfrom
01-09-index_struct.new
Open

Index Struct.new#485
vinistock wants to merge 1 commit intomainfrom
01-09-index_struct.new

Conversation

@vinistock
Copy link
Member

@vinistock vinistock commented Jan 19, 2026

Another step for #392

This PR starts handling Struct.new, creating all definitions related to it. There are a few things regarding behaviour that's interesting:

  • If the first argument is a capitalized string, then Ruby creates an alias for the constant under the Struct namespace
Foo = Struct.new("Bar")
Foo             # => Foo
Struct::Bar # => Foo
  • All other arguments become both an attribute accessor and an instance variable
  • An initialize method is always created (even if there are no fields)
  • The keyword_init parameter changes the signature of initialize to use keyword optional arguments instead of positional optional arguments
  • All structs automatically inherit from Struct

Note: there might be overlap with the handling for Data.define, but I didn't want to make this PR too large. I'll refactor if there's an opportunity for it

Copy link
Member Author

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

@vinistock vinistock self-assigned this Jan 19, 2026
@vinistock vinistock added the enhancement New feature or request label Jan 19, 2026 — with Graphite App
@vinistock vinistock marked this pull request as ready for review January 19, 2026 16:47
@vinistock vinistock requested a review from a team as a code owner January 19, 2026 16:47
call_node.arguments().and_then(|args| args.arguments().iter().next()),
Nesting::Owner,
|indexer, definition_id| {
indexer.nesting_stack.push(Nesting::Owner(definition_id));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we leave this in handle_class_definition since it's the same in both cases?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not always the same. In visit_class_node, this pushes a Nesting::LexicalScope.

}

/// Handles the arguments to `Struct.new` and creates the appropriate definitions
fn handle_struct_fields(&mut self, call_node: &ruby_prism::CallNode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're again trying to do some desugaring/rewriting by introducing a synthetic constant alias. Shouldn't we create a Struct definition instead and create the proper declaration in the resolver?

I think it's another symptom of #471 (review) we're trying to work around.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put a topic for us to discuss in our next meeting.

@vinistock vinistock force-pushed the 01-09-index_struct.new branch from fc5531b to 7a56214 Compare January 19, 2026 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants