Skip to content

Commit c59c6dd

Browse files
committed
Fix overload resolution to accept unknown (empty) type arguments
typecheck methods for Instance, Interface, Singleton, Tuple, Record, and Symbol literal types returned false for empty vertices (untyped arguments with no callers), causing "failed to resolve overloads" errors for calls like `raise unknown`. This was inconsistent with Bool/Nil typecheck which already returned true for empty vertices. Now all these methods distinguish "no types seen" (return true, optimistic) from "types seen but none matched" (return false, real error). Re-evaluation edges ensure correct matching when types arrive.
1 parent 6149c93 commit c59c6dd

7 files changed

Lines changed: 73 additions & 10 deletions

File tree

lib/typeprof/core/ast/sig_type.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ module TypeProf::Core
22
class AST
33
def self.typecheck_for_module(genv, changes, f_mod, f_args, a_vtx, subst)
44
changes.add_edge(genv, a_vtx, changes.target)
5+
found_any = false
56
a_vtx.each_type do |ty|
7+
found_any = true
68
ty = ty.base_type(genv)
79
while ty
810
if ty.mod == f_mod && ty.is_a?(Type::Instance)
@@ -25,7 +27,7 @@ def self.typecheck_for_module(genv, changes, f_mod, f_args, a_vtx, subst)
2527
ty = genv.get_superclass_type(ty, changes, {})
2628
end
2729
end
28-
return false
30+
return !found_any
2931
end
3032

3133
def self.typecheck_for_prepended_modules(genv, changes, a_ty, f_mod, f_args, subst)
@@ -593,7 +595,9 @@ def typecheck(genv, changes, vtx, subst)
593595
return unless cpath
594596
f_mod = genv.resolve_cpath(cpath)
595597
changes.add_edge(genv, vtx, changes.target)
598+
found_any = false
596599
vtx.each_type do |ty|
600+
found_any = true
597601
case ty
598602
when Type::Singleton
599603
if f_mod.module?
@@ -608,7 +612,7 @@ def typecheck(genv, changes, vtx, subst)
608612
end
609613
end
610614
end
611-
false
615+
!found_any
612616
end
613617

614618
def show
@@ -729,7 +733,9 @@ def contravariant_vertex0(genv, changes, vtx, subst)
729733

730734
def typecheck(genv, changes, vtx, subst)
731735
changes.add_edge(genv, vtx, changes.target)
736+
found_any = false
732737
vtx.each_type do |ty|
738+
found_any = true
733739
case ty
734740
when Type::Array
735741
next if ty.elems.size != @types.size
@@ -744,7 +750,7 @@ def typecheck(genv, changes, vtx, subst)
744750
return true
745751
end
746752
end
747-
false
753+
!found_any
748754
end
749755

750756
def show
@@ -799,7 +805,9 @@ def contravariant_vertex0(genv, changes, vtx, subst)
799805

800806
def typecheck(genv, changes, vtx, subst)
801807
changes.add_edge(genv, vtx, changes.target)
808+
found_any = false
802809
vtx.each_type do |ty|
810+
found_any = true
803811
case ty
804812
when Type::Hash
805813
@fields.each do |key, field_node|
@@ -809,7 +817,7 @@ def typecheck(genv, changes, vtx, subst)
809817
return true
810818
end
811819
end
812-
false
820+
!found_any
813821
end
814822

815823
def show
@@ -915,13 +923,15 @@ def contravariant_vertex0(genv, changes, vtx, subst)
915923
def typecheck(genv, changes, vtx, subst)
916924
if @lit.is_a?(::Symbol)
917925
changes.add_edge(genv, vtx, changes.target)
926+
found_any = false
918927
vtx.each_type do |ty|
928+
found_any = true
919929
case ty
920930
when Type::Symbol
921931
return true if ty.sym == @lit
922932
end
923933
end
924-
return false
934+
return !found_any
925935
end
926936
f_mod = get_type(genv).mod
927937
AST.typecheck_for_module(genv, changes, f_mod, [], vtx, subst)

scenario/control/raise-unknown.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
## update
2+
def foobarbaz(unknown)
3+
raise unknown
4+
end
5+
6+
## diagnostics

scenario/rbs/type-alias.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ def test3: (untyped) -> (Integer | String)
2626
end
2727

2828
## diagnostics: test.rb
29-
(10,10)-(10,13): wrong type of arguments
3029

3130
## update: test.rbs
3231
type a = Integer
@@ -44,7 +43,6 @@ def test3: (untyped) -> Integer
4443

4544
## diagnostics: test.rb
4645
(6,10)-(6,13): wrong type of arguments
47-
(10,10)-(10,13): wrong type of arguments
4846

4947
## update: test.rbs
5048
type a = Integer
@@ -61,7 +59,6 @@ def test3: (untyped) -> Integer
6159

6260
## diagnostics: test.rb
6361
(6,10)-(6,13): wrong type of arguments
64-
(10,10)-(10,13): wrong type of arguments
6562

6663
## update: test.rbs
6764
class Bar
@@ -80,4 +77,3 @@ def test3: (untyped) -> Integer
8077

8178
## diagnostics: test.rb
8279
(6,10)-(6,13): wrong type of arguments
83-
(10,10)-(10,13): wrong type of arguments
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## update: test.rbs
2+
class C
3+
def foo: ({ name: String }) -> :record
4+
| (String) -> :str
5+
end
6+
7+
## update: test.rb
8+
def check(unknown)
9+
C.new.foo(unknown)
10+
end
11+
12+
## diagnostics: test.rb
13+
14+
## assert
15+
class Object
16+
def check: (untyped) -> (:record | :str)
17+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## update: test.rbs
2+
class C
3+
def foo: (singleton(String)) -> :str
4+
| (singleton(Integer)) -> :int
5+
end
6+
7+
## update: test.rb
8+
def check(unknown)
9+
C.new.foo(unknown)
10+
end
11+
12+
## diagnostics: test.rb
13+
14+
## assert
15+
class Object
16+
def check: (untyped) -> (:int | :str)
17+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## update: test.rbs
2+
class C
3+
def foo: ([String, Integer]) -> :tuple
4+
| (String) -> :str
5+
end
6+
7+
## update: test.rb
8+
def check(unknown)
9+
C.new.foo(unknown)
10+
end
11+
12+
## diagnostics: test.rb
13+
14+
## assert
15+
class Object
16+
def check: (untyped) -> (:str | :tuple)
17+
end

scenario/rbs/untyped-for-overload.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ def check
1111

1212
## assert
1313
class Object
14-
def check: -> untyped
14+
def check: -> (:A | :B)
1515
end

0 commit comments

Comments
 (0)