Skip to content

case/when record type narrowing - #1568

Open
HoneyryderChuck wants to merge 1 commit into
soutaro:masterfrom
HoneyryderChuck:narrow-type-record-on-case-param
Open

case/when record type narrowing#1568
HoneyryderChuck wants to merge 1 commit into
soutaro:masterfrom
HoneyryderChuck:narrow-type-record-on-case-param

Conversation

@HoneyryderChuck

Copy link
Copy Markdown

This is a WIP to add type narrowing support for the following use-case:

# @type var x: { type: :foo, value: Integer } | {type: :bar, value: String }
case x[:type]
when :foo
  # x[:value] is an integer
when :bar
  # x[:value] is a string
end

@soutaro I'm needing some assistance on how to implement this. I'm looking at the type inference code, particularly the CaseWhen statement, but I'm not sure how to cleanly implement this. It seems that, when doing when_pats.add_pattern(pat) {|test, constr| constr.synthesize(test) }, the value for lvar should be correctly inferred, but this annotation does not bubble up to the x from the case condition, which in the case statement is represented as a s(:send, s(:lvar, :x), :[], s(:sym, :type))) node. My assumption is that the same limitation applies for the same method-call pattern, i.e. if x were declared as A | B and there was a method foo which returns :foo for A and :bar for B, the when block would not be able to distinguish between them.

@soutaro soutaro modified the milestones: Steep 2.0, Steep 2.1 Apr 9, 2026
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