Skip to content

Commit f9e67e6

Browse files
sekito1107mame
authored andcommitted
Fix type inference for multiple assignment of generic Array[T]
Handle Type::Instance (e.g. from RBS Array[T]) in MAsgnBox#run0 by distributing the element type to variables. Previously, only Type::Array (literal arrays) was handled correctly. For other types, it assigned the entire array object to the first variable on the left-hand side, leaving subsequent variables as untyped.
1 parent a8a857d commit f9e67e6

2 files changed

Lines changed: 36 additions & 11 deletions

File tree

lib/typeprof/core/graph/box.rb

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,25 +1156,27 @@ def destroy(genv)
11561156
def ret = @rhs
11571157

11581158
def run0(genv, changes)
1159-
edges = []
11601159
@value.each_type do |ty|
11611160
# TODO: call to_ary?
11621161
case ty
11631162
when Type::Array
1164-
edges.concat(ty.splat_assign(genv, @lefts, @rest_elem, @rights))
1165-
else
1166-
if @lefts.size >= 1
1167-
edges << [Source.new(ty), @lefts[0]]
1168-
elsif @rights && @rights.size >= 1
1169-
edges << [Source.new(ty), @rights[0]]
1163+
ty.splat_assign(genv, @lefts, @rest_elem, @rights).each do |src, dst|
1164+
changes.add_edge(genv, src, dst)
1165+
end
1166+
when Type::Instance
1167+
if ty.mod == genv.mod_ary && (elem_vtx = ty.args[0])
1168+
@lefts.each {|lhs| changes.add_edge(genv, elem_vtx, lhs) }
1169+
changes.add_edge(genv, elem_vtx, @rest_elem) if @rest_elem
1170+
@rights&.each {|rhs| changes.add_edge(genv, elem_vtx, rhs) }
11701171
else
1171-
edges << [Source.new(ty), @rest_elem]
1172+
lhs = @lefts[0] || (@rights && @rights[0]) || @rest_elem
1173+
changes.add_edge(genv, Source.new(ty), lhs) if lhs
11721174
end
1175+
else
1176+
lhs = @lefts[0] || (@rights && @rights[0]) || @rest_elem
1177+
changes.add_edge(genv, Source.new(ty), lhs) if lhs
11731178
end
11741179
end
1175-
edges.each do |src, dst|
1176-
changes.add_edge(genv, src, dst)
1177-
end
11781180
end
11791181
end
11801182

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## update: test.rbs
2+
class Foo
3+
def get_ints: () -> Array[Integer]
4+
end
5+
6+
## update: test.rb
7+
class Foo
8+
def test_masgn
9+
a, b, c = get_ints
10+
[a, b, c]
11+
end
12+
13+
def test_star
14+
a, *rest = get_ints
15+
rest
16+
end
17+
end
18+
19+
## assert: test.rb
20+
class Foo
21+
def test_masgn: -> [Integer, Integer, Integer]
22+
def test_star: -> Array[Integer]
23+
end

0 commit comments

Comments
 (0)