Skip to content

Commit 6f64fba

Browse files
mameclaude
andcommitted
Support narrowing for if (y = x) assignment in condition
LocalVariableWriteNode now provides narrowings for the assigned variable, so `if (y = x)` correctly narrows y to non-nil in the then branch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 84cd000 commit 6f64fba

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

lib/typeprof/core/ast/variable.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ def retrieve_at(pos, &blk)
6868
super(pos, &blk)
6969
end
7070

71+
def narrowings
72+
@narrowings ||= [
73+
Narrowing.new({ @var => Narrowing::NilConstraint.new(false) }),
74+
Narrowing.new({ @var => Narrowing::NilConstraint.new(true) }),
75+
]
76+
end
77+
7178
def modified_vars(tbl, vars)
7279
vars << self.var if tbl.include?(self.var)
7380
end

scenario/flow/if_assign.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
## update
2+
def foo(x)
3+
if (y = x)
4+
y.to_sym
5+
end
6+
end
7+
foo(nil)
8+
foo("hello")
9+
10+
## assert
11+
class Object
12+
def foo: (String?) -> Symbol?
13+
end
14+
15+
## update
16+
def foo(x, z)
17+
if x && (y = z)
18+
y.to_sym
19+
end
20+
end
21+
foo(true, "hello")
22+
foo(true, nil)
23+
foo(false, nil)
24+
25+
## assert
26+
class Object
27+
def foo: (bool, String?) -> Symbol?
28+
end
29+
30+
## update
31+
def foo(z)
32+
if (y = z) && y.length > 0
33+
y.to_sym
34+
end
35+
end
36+
foo("hello")
37+
foo(nil)
38+
39+
## assert
40+
class Object
41+
def foo: (String?) -> Symbol?
42+
end

0 commit comments

Comments
 (0)