Skip to content

Fix false positive: Struct.new(keyword_init: true) members are optional - #1269

Open
apiology wants to merge 3 commits into
castwide:masterfrom
apiology:fix-1268-struct-keyword-init-optional
Open

apiology wants to merge 3 commits into
castwide:masterfrom
apiology:fix-1268-struct-keyword-init-optional

Conversation

@apiology

@apiology apiology commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

solargraph typecheck --level strong treated every member of a Struct.new(..., keyword_init: true)-generated class as a required keyword argument, reporting a false "Missing keyword argument" error when a call site omitted one. At runtime, keyword_init: true Struct members default to nil when omitted, exactly like ordinary Struct.new(...) members.

lib/solargraph/convention/struct_definition.rb generated Pin::Parameter pins for keyword-init Struct members with decl: :kwarg (required). Changed to decl: :kwoptarg (optional), matching how TypeChecker#parameterized_arity_problems_for already distinguishes required (:kwarg) from optional (:kwoptarg) keyword parameters.

Data.define (lib/solargraph/convention/data_definition.rb) is untouched ��� its members genuinely are required at runtime, so :kwarg stays correct there.

class Watch < Struct.new(:name, :time, keyword_init: true); end

class Caller
  # @return [Watch]
  def go
    Watch.new(name: 'foo') # no longer flagged as missing `time:`
  end
end

Fixes #1268

Test plan

  • Added spec asserting keyword-init Struct parameters have decl == :kwoptarg
  • Added typecheck spec reproducing the issue's exact repro, asserting no "Missing keyword argument" problem
  • bundle exec rspec (full suite): 1626 examples, 0 failures
  • bundle exec rubocop on changed files: no offenses
  • Manually ran solargraph typecheck --level strong against the issue's repro: 0 problems found (previously reported the false positive)

���� Generated with Claude Code

https://claude.ai/code/session_01TqwAY5yf6K1ZQdYoSZDkmy

Solargraph generated a :kwarg (required) parameter pin for every member of
a Struct.new(..., keyword_init: true) class, so typecheck --level strong
reported "Missing keyword argument" when a call site omitted one. At
runtime, keyword_init Struct members default to nil like ordinary Struct
members, so they should be :kwoptarg (optional) instead.

Fixes castwide#1268

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqwAY5yf6K1ZQdYoSZDkmy
Removing it does not change strong typecheck output (531 problems,
same set, before and after) -- inference already resolves this
correctly, so no @sg-ignore is needed either.
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.

Struct.new(keyword_init: true) members treated as required, not optional/nil-defaulting

1 participant