Skip to content

Commit 3274dec

Browse files
committed
Fix crash in break in loop
1 parent 14ffbcf commit 3274dec

2 files changed

Lines changed: 83 additions & 9 deletions

File tree

lib/typeprof/core/graph/change_set.rb

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ def initialize(node, target)
66
@new_vertexes = {}
77
@covariant_types = {}
88
@contravariant_types = {}
9-
@edges = []
10-
@new_edges = []
9+
@edges = {}
10+
@new_edges = {}
1111
@boxes = {}
1212
@new_boxes = {}
1313
@diagnostics = []
@@ -62,7 +62,14 @@ def new_contravariant_vertex(genv, sig_type_node)
6262
end
6363

6464
def add_edge(genv, src, dst)
65-
@new_edges << [src, dst]
65+
key = [src, dst]
66+
return if @new_edges[key]
67+
@new_edges[key] = @edges[key] || begin
68+
bridge = Vertex.new(@node)
69+
src.add_edge(genv, bridge)
70+
bridge.add_edge(genv, dst)
71+
bridge
72+
end
6673
end
6774

6875
# TODO: if an edge is removed during one analysis, we may need to remove sub-boxes?
@@ -158,12 +165,12 @@ def add_depended_superclass(mod)
158165
end
159166

160167
def reinstall(genv)
161-
@new_edges.uniq!
162-
@new_edges.each do |src, dst|
163-
src.add_edge(genv, dst) unless @edges.include?([src, dst])
164-
end
165-
@edges.each do |src, dst|
166-
src.remove_edge(genv, dst) unless @new_edges.include?([src, dst])
168+
@edges.each do |key, bridge|
169+
unless @new_edges.key?(key)
170+
src, dst = key
171+
src.remove_edge(genv, bridge)
172+
bridge.remove_edge(genv, dst)
173+
end
167174
end
168175
@edges, @new_edges = @new_edges, @edges
169176
@new_edges.clear

scenario/control/break2.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
## update
2+
def foo
3+
count = 0
4+
loop do
5+
count += 1
6+
break count if count == 3
7+
end
8+
end
9+
10+
## assert
11+
class Object
12+
def foo: -> Integer
13+
end
14+
15+
## update
16+
def foo
17+
count = 0
18+
loop do
19+
count += 1
20+
begin
21+
break count if count == 3
22+
rescue
23+
break count
24+
end
25+
end
26+
end
27+
28+
## assert
29+
class Object
30+
def foo: -> Integer
31+
end
32+
33+
## update
34+
def foo
35+
count = 0
36+
loop do
37+
count += 1
38+
begin
39+
break count if count == 3
40+
rescue
41+
break 'str'
42+
end
43+
end
44+
end
45+
46+
## assert
47+
class Object
48+
def foo: -> (Integer | String)
49+
end
50+
51+
## update
52+
def foo
53+
count = 0
54+
loop do
55+
count += 1
56+
begin
57+
# break count if count == 3
58+
rescue
59+
break 'str'
60+
end
61+
end
62+
end
63+
64+
## assert
65+
class Object
66+
def foo: -> String
67+
end

0 commit comments

Comments
 (0)