Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/typeprof/core/ast/misc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@ def install0(genv)
vtx = @expr.install(genv)

a_args = ActualArguments.new([], [], nil, nil)
vtx = @changes.add_method_call_box(genv, vtx, :to_a, a_args, false).ret
to_a_vtx = @changes.add_method_call_box(genv, vtx, :to_a, a_args, false, suppress_errors: true).ret

@changes.add_splat_box(genv, vtx).ret
@changes.add_splat_box(genv, to_a_vtx, nil, vtx).ret
end
end

Expand Down
24 changes: 17 additions & 7 deletions lib/typeprof/core/graph/box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -600,11 +600,13 @@ def wrong_return_type(f_ret_show, changes)
end

class SplatBox < Box
def initialize(node, genv, ary, idx)
def initialize(node, genv, ary, idx, orig = nil)
super(node)
@ary = ary
@idx = idx
@orig = orig
@ary.add_edge(genv, self)
@orig.add_edge(genv, self) if @orig
@ret = Vertex.new(node)
end

Expand All @@ -629,6 +631,12 @@ def run0(genv, changes)
"???"
end
end
# For types where to_a is not defined, [*x] wraps x as [x]
if @orig && @ary.types.empty?
@orig.each_type do |ty|
changes.add_edge(genv, Source.new(ty), @ret)
end
end
end
end

Expand Down Expand Up @@ -992,7 +1000,7 @@ def run0(genv, changes)
end

class MethodCallBox < Box
def initialize(node, genv, recv, mid, a_args, subclasses)
def initialize(node, genv, recv, mid, a_args, subclasses, suppress_errors: false)
raise mid.to_s unless mid
super(node)
@recv = recv.new_vertex(genv, node)
Expand All @@ -1003,6 +1011,7 @@ def initialize(node, genv, recv, mid, a_args, subclasses)
@a_args.block.add_edge(genv, self) if @a_args.block
@ret = Vertex.new(node)
@subclasses = subclasses
@suppress_errors = suppress_errors
@generics = {}
end

Expand All @@ -1014,10 +1023,11 @@ def run0(genv, changes)
error_count = 0
resolve(genv, changes) do |me, ty, mid, orig_ty|
if !me
# TODO: undefined method error
if error_count < 3
meth = @node.mid_code_range ? :mid_code_range : :code_range
changes.add_diagnostic(meth, "undefined method: #{ orig_ty.show }##{ mid }")
unless @suppress_errors
if error_count < 3
meth = @node.mid_code_range ? :mid_code_range : :code_range
changes.add_diagnostic(meth, "undefined method: #{ orig_ty.show }##{ mid }")
end
end
error_count += 1
elsif me.builtin && me.builtin[changes, @node, orig_ty, @a_args, @ret]
Expand Down Expand Up @@ -1062,7 +1072,7 @@ def run0(genv, changes)
edges.each do |src, dst|
changes.add_edge(genv, src, dst)
end
if error_count > 3
if error_count > 3 && !@suppress_errors
meth = @node.mid_code_range ? :mid_code_range : :code_range
changes.add_diagnostic(meth, "... and other #{ error_count - 3 } errors")
end
Expand Down
12 changes: 6 additions & 6 deletions lib/typeprof/core/graph/change_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,19 @@ def add_edge(genv, src, dst)

# TODO: if an edge is removed during one analysis, we may need to remove sub-boxes?

def add_method_call_box(genv, recv, mid, a_args, subclasses)
key = [:mcall, recv, mid, a_args, subclasses]
@new_boxes[key] ||= MethodCallBox.new(@node, genv, recv, mid, a_args, subclasses)
def add_method_call_box(genv, recv, mid, a_args, subclasses, suppress_errors: false)
key = [:mcall, recv, mid, a_args, subclasses, suppress_errors]
@new_boxes[key] ||= MethodCallBox.new(@node, genv, recv, mid, a_args, subclasses, suppress_errors: suppress_errors)
end

def add_escape_box(genv, a_ret)
key = [:return, a_ret]
@new_boxes[key] ||= EscapeBox.new(@node, genv, a_ret)
end

def add_splat_box(genv, arg, idx = nil)
key = [:splat, arg, idx]
@new_boxes[key] ||= SplatBox.new(@node, genv, arg, idx)
def add_splat_box(genv, arg, idx = nil, orig = nil)
key = [:splat, arg, idx, orig]
@new_boxes[key] ||= SplatBox.new(@node, genv, arg, idx, orig)
end

def add_hash_splat_box(genv, arg, unified_key, unified_val)
Expand Down
12 changes: 12 additions & 0 deletions scenario/known-issues/splat-union-fallback.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## update
def foo(x)
[*x]
end

foo([:int])
foo(:sym)

## assert
class Object
def foo: (Array[:int] | :sym) -> Array[:int | :sym]
end
Loading