typeprof 0.4.2 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -2
- data/Gemfile.lock +3 -3
- data/README.md +6 -0
- data/lib/typeprof/analyzer.rb +97 -84
- data/lib/typeprof/arguments.rb +27 -19
- data/lib/typeprof/block.rb +5 -2
- data/lib/typeprof/builtin.rb +14 -4
- data/lib/typeprof/config.rb +10 -6
- data/lib/typeprof/container-type.rb +117 -101
- data/lib/typeprof/export.rb +1 -1
- data/lib/typeprof/import.rb +44 -22
- data/lib/typeprof/method.rb +70 -12
- data/lib/typeprof/type.rb +108 -89
- data/lib/typeprof/version.rb +1 -1
- data/smoke/arguments2.rb +1 -1
- data/smoke/array11.rb +1 -1
- data/smoke/array6.rb +2 -2
- data/smoke/array8.rb +1 -1
- data/smoke/block-args2.rb +3 -3
- data/smoke/block-args3.rb +4 -4
- data/smoke/block-blockarg.rb +1 -1
- data/smoke/block-kwarg.rb +1 -1
- data/smoke/block10.rb +1 -1
- data/smoke/block5.rb +1 -1
- data/smoke/constant2.rb +1 -2
- data/smoke/demo5.rb +1 -1
- data/smoke/demo9.rb +1 -1
- data/smoke/hash-fetch.rb +3 -3
- data/smoke/hash-merge-bang.rb +11 -0
- data/smoke/hash1.rb +3 -2
- data/smoke/hash3.rb +1 -1
- data/smoke/inheritance2.rb +2 -2
- data/smoke/ivar2.rb +2 -2
- data/smoke/kernel-class.rb +1 -1
- data/smoke/keyword4.rb +1 -1
- data/smoke/kwsplat1.rb +2 -2
- data/smoke/kwsplat2.rb +1 -1
- data/smoke/multiple-superclass.rb +1 -1
- data/smoke/parameterizedd-self.rb +2 -2
- data/smoke/pattern-match1.rb +23 -0
- data/smoke/pattern-match2.rb +15 -0
- data/smoke/rbs-tyvar3.rb +11 -19
- data/smoke/rbs-tyvar3.rbs +4 -3
- data/smoke/rbs-tyvar4.rb +36 -0
- data/smoke/rbs-tyvar5.rb +12 -0
- data/smoke/rbs-tyvar5.rbs +8 -0
- data/smoke/struct.rb +2 -2
- data/smoke/uninitialize-var.rb +12 -0
- data/smoke/union-recv.rb +2 -2
- data/typeprof.gemspec +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d60066fe3965ec65f9885e311f856277d0e41330478489c026fdf6b387ba2ba
|
4
|
+
data.tar.gz: 963b66fe97d98207d72645011bcd012368937ded76278d92a4b677b961c92cdc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a40e89e05c1680480eb66798863ab99a4b38b3faaacdc471a6cdd45dfc1f897efcc8f613800ef28e5bc722c3504dec510ca943435873b6cb765a27f1bb073425
|
7
|
+
data.tar.gz: 94dddf2c3e465ee19093ce571d50440293118b07ab7c90203aa5ccb40c4f9eb9afe1059eff045c965006affa8f0d66d141be2064feddf9a2b1f8384f8cadae64
|
data/.github/workflows/main.yml
CHANGED
@@ -17,9 +17,8 @@ jobs:
|
|
17
17
|
uses: ruby/setup-ruby@v1
|
18
18
|
with:
|
19
19
|
ruby-version: ${{ matrix.ruby-version }}
|
20
|
-
- name:
|
20
|
+
- name: Bundle install
|
21
21
|
run: |
|
22
|
-
cd rbs && bundle install && bundle exec rake parser && cd ..
|
23
22
|
bundle install
|
24
23
|
- name: Run the test suite
|
25
24
|
run: |
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
typeprof (0.4
|
5
|
-
rbs (>= 0.
|
4
|
+
typeprof (0.5.4)
|
5
|
+
rbs (>= 0.17.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
@@ -11,7 +11,7 @@ GEM
|
|
11
11
|
docile (1.3.2)
|
12
12
|
power_assert (1.2.0)
|
13
13
|
rake (13.0.1)
|
14
|
-
rbs (0.
|
14
|
+
rbs (0.17.0)
|
15
15
|
simplecov (0.19.1)
|
16
16
|
docile (~> 1.1)
|
17
17
|
simplecov-html (~> 0.11)
|
data/README.md
CHANGED
data/lib/typeprof/analyzer.rb
CHANGED
@@ -87,6 +87,11 @@ module TypeProf
|
|
87
87
|
@recv_ty = recv_ty
|
88
88
|
@blk_ty = blk_ty
|
89
89
|
@mod_func = mod_func
|
90
|
+
|
91
|
+
return if recv_ty == :top #OK
|
92
|
+
recv_ty.each_child_global do |ty|
|
93
|
+
raise ty.inspect if !ty.is_a?(Type::Instance) && !ty.is_a?(Type::Class) && ty != Type.any
|
94
|
+
end
|
90
95
|
end
|
91
96
|
|
92
97
|
attr_reader :recv_ty, :blk_ty, :mod_func
|
@@ -129,11 +134,7 @@ module TypeProf
|
|
129
134
|
elems2 = type_params[id]
|
130
135
|
if elems2
|
131
136
|
if elems != elems2
|
132
|
-
|
133
|
-
type_params[id] = elems.zip(elems2).map {|elem1, elem2| elem1.union(elem2) }
|
134
|
-
else
|
135
|
-
type_params[id] = elems.union(elems2)
|
136
|
-
end
|
137
|
+
type_params[id] = elems.union(elems2)
|
137
138
|
end
|
138
139
|
else
|
139
140
|
type_params[id] = elems
|
@@ -151,6 +152,8 @@ module TypeProf
|
|
151
152
|
tys.each do |ty|
|
152
153
|
raise "nil cannot be pushed to the stack" if ty.nil?
|
153
154
|
ty.each_child do |ty|
|
155
|
+
raise if ty.is_a?(Type::Var)
|
156
|
+
#raise if ty.is_a?(Type::Instance) && ty.klass.type_params.size > 1
|
154
157
|
raise "Array cannot be pushed to the stack" if ty.is_a?(Type::Array)
|
155
158
|
raise "Hash cannot be pushed to the stack" if ty.is_a?(Type::Hash)
|
156
159
|
end
|
@@ -249,6 +252,8 @@ module TypeProf
|
|
249
252
|
@rbs_reader = RBSReader.new
|
250
253
|
|
251
254
|
@terminated = false
|
255
|
+
|
256
|
+
@anonymous_struct_gen_id = 0
|
252
257
|
end
|
253
258
|
|
254
259
|
attr_reader :return_envs, :loaded_features, :rbs_reader
|
@@ -293,20 +298,11 @@ module TypeProf
|
|
293
298
|
attr_reader :kind, :superclass, :modules, :consts, :methods, :ivars, :cvars, :absolute_path
|
294
299
|
attr_accessor :name, :klass_obj
|
295
300
|
|
296
|
-
def include_module(mod, absolute_path)
|
297
|
-
# XXX: need to check if mod is already included by the ancestors?
|
298
|
-
absolute_paths = @modules[false][mod]
|
299
|
-
unless absolute_paths
|
300
|
-
@modules[false][mod] = absolute_paths = Utils::MutableSet.new
|
301
|
-
end
|
302
|
-
absolute_paths << absolute_path
|
303
|
-
end
|
304
|
-
|
305
|
-
def extend_module(mod, absolute_path)
|
301
|
+
def include_module(mod, singleton, absolute_path)
|
306
302
|
# XXX: need to check if mod is already included by the ancestors?
|
307
|
-
absolute_paths = @modules[
|
303
|
+
absolute_paths = @modules[singleton][mod]
|
308
304
|
unless absolute_paths
|
309
|
-
@modules[
|
305
|
+
@modules[singleton][mod] = absolute_paths = Utils::MutableSet.new
|
310
306
|
end
|
311
307
|
absolute_paths << absolute_path
|
312
308
|
end
|
@@ -353,7 +349,7 @@ module TypeProf
|
|
353
349
|
end
|
354
350
|
end
|
355
351
|
|
356
|
-
def include_module(including_mod, included_mod, absolute_path)
|
352
|
+
def include_module(including_mod, included_mod, singleton, absolute_path)
|
357
353
|
return if included_mod == Type.any
|
358
354
|
|
359
355
|
including_mod = @class_defs[including_mod.idx]
|
@@ -361,7 +357,7 @@ module TypeProf
|
|
361
357
|
if included_mod.is_a?(Type::Class)
|
362
358
|
included_mod = @class_defs[included_mod.idx]
|
363
359
|
if included_mod && included_mod.kind == :module
|
364
|
-
including_mod.include_module(included_mod, absolute_path)
|
360
|
+
including_mod.include_module(included_mod, singleton, absolute_path)
|
365
361
|
else
|
366
362
|
warn "including something that is not a module"
|
367
363
|
end
|
@@ -369,20 +365,6 @@ module TypeProf
|
|
369
365
|
end
|
370
366
|
end
|
371
367
|
|
372
|
-
def extend_module(extending_mod, extended_mod, absolute_path)
|
373
|
-
extending_mod = @class_defs[extending_mod.idx]
|
374
|
-
extended_mod.each_child do |extended_mod|
|
375
|
-
if extended_mod.is_a?(Type::Class)
|
376
|
-
extended_mod = @class_defs[extended_mod.idx]
|
377
|
-
if extended_mod && extended_mod.kind == :module
|
378
|
-
extending_mod.extend_module(extended_mod, absolute_path)
|
379
|
-
else
|
380
|
-
warn "extending something that is not a module"
|
381
|
-
end
|
382
|
-
end
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
368
|
def cbase_path(cbase)
|
387
369
|
cbase && cbase.idx != 1 ? @class_defs[cbase.idx].name : []
|
388
370
|
end
|
@@ -417,8 +399,9 @@ module TypeProf
|
|
417
399
|
|
418
400
|
idx = @class_defs.size
|
419
401
|
superclass = Type::Builtin[:struct]
|
420
|
-
|
421
|
-
|
402
|
+
name = "AnonymousStruct_generated_#{ @anonymous_struct_gen_id += 1 }"
|
403
|
+
@class_defs[idx] = ClassDef.new(:class, [name], superclass.idx, ep.ctx.iseq.absolute_path)
|
404
|
+
klass = Type::Class.new(:class, idx, [], superclass, name)
|
422
405
|
@class_defs[idx].klass_obj = klass
|
423
406
|
|
424
407
|
@struct_defs[ep] = klass
|
@@ -572,9 +555,7 @@ module TypeProf
|
|
572
555
|
|
573
556
|
ret_ty = @return_values[callee_ctx] ||= Type.bot
|
574
557
|
if ret_ty != Type.bot
|
575
|
-
|
576
|
-
ctn[ret_ty, caller_ep, @return_envs[caller_ep]]
|
577
|
-
end
|
558
|
+
ctn[ret_ty, caller_ep, @return_envs[caller_ep]]
|
578
559
|
end
|
579
560
|
end
|
580
561
|
|
@@ -632,7 +613,7 @@ module TypeProf
|
|
632
613
|
entry = @tbl[site] ||= Entry.new(!ep, {}, Type.bot, Utils::MutableSet.new)
|
633
614
|
if ep
|
634
615
|
if entry.rbs_declared
|
635
|
-
|
616
|
+
unless Type.match?(ty, entry.type)
|
636
617
|
scratch.warn(ep, "inconsistent assignment to RBS-declared global variable")
|
637
618
|
return
|
638
619
|
end
|
@@ -651,6 +632,7 @@ module TypeProf
|
|
651
632
|
end
|
652
633
|
|
653
634
|
def get_ivar(recv)
|
635
|
+
recv = recv.base_type while recv.respond_to?(:base_type)
|
654
636
|
case recv
|
655
637
|
when Type::Class
|
656
638
|
[@class_defs[recv.idx], true]
|
@@ -884,26 +866,41 @@ module TypeProf
|
|
884
866
|
def pend_method_execution(iseq, meth, recv, mid, cref)
|
885
867
|
ctx = Context.new(iseq, cref, mid)
|
886
868
|
ep = ExecutionPoint.new(ctx, 0, nil)
|
887
|
-
locals = [Type.
|
888
|
-
|
889
|
-
|
869
|
+
locals = [Type.nil] * iseq.locals.size
|
870
|
+
|
871
|
+
fargs_format = iseq.fargs_format
|
872
|
+
lead_num = fargs_format[:lead_num] || 0
|
873
|
+
post_num = fargs_format[:post_num] || 0
|
874
|
+
post_index = fargs_format[:post_start]
|
875
|
+
rest_index = fargs_format[:rest_start]
|
876
|
+
keyword = fargs_format[:keyword]
|
877
|
+
kw_index = fargs_format[:kwbits] - keyword.size if keyword
|
878
|
+
kwrest_index = fargs_format[:kwrest]
|
879
|
+
block_index = fargs_format[:block_start]
|
880
|
+
opt = fargs_format[:opt] || [0]
|
881
|
+
|
882
|
+
(lead_num + opt.size - 1).times {|i| locals[i] = Type.any }
|
883
|
+
post_num.times {|i| locals[i + post_index] = Type.any } if post_index
|
884
|
+
locals[rest_index] = Type.any if rest_index
|
890
885
|
if keyword
|
891
|
-
kw_start = iseq.fargs_format[:kwbits]
|
892
|
-
kw_start -= iseq.fargs_format[:keyword].size if kw_start
|
893
886
|
keyword.each_with_index do |kw, i|
|
894
887
|
case
|
895
888
|
when kw.is_a?(Symbol) # required keyword
|
889
|
+
locals[kw_index + i] = Type.any
|
896
890
|
when kw.size == 2 # optional keyword (default value is a literal)
|
897
891
|
_key, default_ty = *kw
|
898
892
|
default_ty = Type.guess_literal_type(default_ty)
|
899
|
-
default_ty = default_ty.
|
900
|
-
locals[
|
893
|
+
default_ty = default_ty.base_type if default_ty.is_a?(Type::Literal)
|
894
|
+
locals[kw_index + i] = default_ty.union(Type.any)
|
901
895
|
else # optional keyword (default value is an expression)
|
896
|
+
locals[kw_index + i] = Type.any
|
902
897
|
end
|
903
898
|
end
|
904
899
|
end
|
900
|
+
locals[kwrest_index] = Type.any if kwrest_index
|
901
|
+
locals[block_index] = Type.nil if block_index
|
905
902
|
|
906
|
-
env = Env.new(StaticEnv.new(recv, Type.
|
903
|
+
env = Env.new(StaticEnv.new(recv, Type.nil, false), locals, [], Utils::HashWrapper.new({}))
|
907
904
|
|
908
905
|
@pending_execution[iseq] ||= [:method, [meth, ep, env]]
|
909
906
|
end
|
@@ -986,7 +983,7 @@ module TypeProf
|
|
986
983
|
when kw.size == 2 # optional keyword (default value is a literal)
|
987
984
|
key, default_ty = *kw
|
988
985
|
default_ty = Type.guess_literal_type(default_ty)
|
989
|
-
default_ty = default_ty.
|
986
|
+
default_ty = default_ty.base_type if default_ty.is_a?(Type::Literal)
|
990
987
|
req = false
|
991
988
|
else # optional keyword (default value is an expression)
|
992
989
|
key, = kw
|
@@ -1029,7 +1026,17 @@ module TypeProf
|
|
1029
1026
|
ty = Type::Literal.new(str, Type::Instance.new(Type::Builtin[:str]))
|
1030
1027
|
env = env.push(ty)
|
1031
1028
|
when :putself
|
1032
|
-
|
1029
|
+
ty = env.static_env.recv_ty
|
1030
|
+
if ty.is_a?(Type::Instance)
|
1031
|
+
klass = ty.klass
|
1032
|
+
if klass.type_params.size >= 1
|
1033
|
+
ty = Type::ContainerType.create_empty_instance(klass)
|
1034
|
+
env, ty = localize_type(ty, env, ep, AllocationSite.new(ep))
|
1035
|
+
else
|
1036
|
+
ty = Type::Instance.new(klass)
|
1037
|
+
end
|
1038
|
+
env, ty = localize_type(ty, env, ep)
|
1039
|
+
end
|
1033
1040
|
env = env.push(ty)
|
1034
1041
|
when :newarray, :newarraykwsplat
|
1035
1042
|
len, = operands
|
@@ -1128,35 +1135,29 @@ module TypeProf
|
|
1128
1135
|
else
|
1129
1136
|
if existing_klass != Type.any
|
1130
1137
|
error(ep, "the class \"#{ id }\" is #{ existing_klass.screen_name(self) }")
|
1131
|
-
id = :"#{ id }(dummy)"
|
1132
1138
|
end
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
superclass = Type::Builtin[:obj]
|
1145
|
-
elsif superclass.is_a?(Type::Instance)
|
1146
|
-
warn(ep, "superclass is an instance; Object is used instead")
|
1147
|
-
superclass = Type::Builtin[:obj]
|
1148
|
-
else
|
1149
|
-
warn(ep, "superclass is not a class; Object is used instead")
|
1150
|
-
superclass = Type::Builtin[:obj]
|
1151
|
-
end
|
1152
|
-
else # module
|
1153
|
-
superclass = nil
|
1154
|
-
end
|
1155
|
-
if cbase == Type.any
|
1156
|
-
klass = Type.any
|
1139
|
+
if type == :class
|
1140
|
+
if superclass.is_a?(Type::Class)
|
1141
|
+
# okay
|
1142
|
+
elsif superclass == Type.any
|
1143
|
+
warn(ep, "superclass is any; Object is used instead")
|
1144
|
+
superclass = Type::Builtin[:obj]
|
1145
|
+
elsif superclass == Type.nil
|
1146
|
+
superclass = Type::Builtin[:obj]
|
1147
|
+
elsif superclass.is_a?(Type::Instance)
|
1148
|
+
warn(ep, "superclass is an instance; Object is used instead")
|
1149
|
+
superclass = Type::Builtin[:obj]
|
1157
1150
|
else
|
1158
|
-
|
1151
|
+
warn(ep, "superclass is not a class; Object is used instead")
|
1152
|
+
superclass = Type::Builtin[:obj]
|
1159
1153
|
end
|
1154
|
+
else # module
|
1155
|
+
superclass = nil
|
1156
|
+
end
|
1157
|
+
if cbase == Type.any
|
1158
|
+
klass = Type.any
|
1159
|
+
else
|
1160
|
+
klass = new_class(cbase, id, [], superclass, ep.ctx.iseq.absolute_path)
|
1160
1161
|
end
|
1161
1162
|
end
|
1162
1163
|
singleton = false
|
@@ -1700,15 +1701,27 @@ module TypeProf
|
|
1700
1701
|
end
|
1701
1702
|
|
1702
1703
|
when :checktype
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
if res
|
1709
|
-
ty = Type::Instance.new(Type::Builtin[:true])
|
1704
|
+
kind, = operands
|
1705
|
+
case kind
|
1706
|
+
when 5 then klass = :str # T_STRING
|
1707
|
+
when 7 then klass = :ary # T_ARRAY
|
1708
|
+
when 8 then klass = :hash # T_HASH
|
1710
1709
|
else
|
1711
|
-
|
1710
|
+
raise NotImplementedError
|
1711
|
+
end
|
1712
|
+
env, (val,) = env.pop(1)
|
1713
|
+
ty = Type.bot
|
1714
|
+
val.each_child do |val|
|
1715
|
+
#globalize_type(val, env, ep).each_child_global do |val|
|
1716
|
+
val = val.base_type while val.respond_to?(:base_type)
|
1717
|
+
case val
|
1718
|
+
when Type::Instance.new(Type::Builtin[klass])
|
1719
|
+
ty = ty.union(Type::Instance.new(Type::Builtin[:true]))
|
1720
|
+
when Type.any
|
1721
|
+
ty = Type.bool
|
1722
|
+
else
|
1723
|
+
ty = ty.union(Type::Instance.new(Type::Builtin[:false]))
|
1724
|
+
end
|
1712
1725
|
end
|
1713
1726
|
env = env.push(ty)
|
1714
1727
|
else
|
@@ -1946,7 +1959,7 @@ module TypeProf
|
|
1946
1959
|
end
|
1947
1960
|
end
|
1948
1961
|
|
1949
|
-
@block_to_ctx[blk.block_body]
|
1962
|
+
@block_to_ctx[blk.block_body]&.each do |blk_ctx|
|
1950
1963
|
ret_ty = ret_ty.union(@return_values[blk_ctx]) if @return_values[blk_ctx]
|
1951
1964
|
end
|
1952
1965
|
end
|
data/lib/typeprof/arguments.rb
CHANGED
@@ -25,7 +25,7 @@ module TypeProf
|
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
28
|
-
def consistent_with_method_signature?(msig
|
28
|
+
def consistent_with_method_signature?(msig)
|
29
29
|
aargs = @lead_tys.dup
|
30
30
|
|
31
31
|
# aargs: lead_tys, rest_ty
|
@@ -36,53 +36,61 @@ module TypeProf
|
|
36
36
|
(lower_bound..upper_bound).each do |n|
|
37
37
|
# BUG: @rest_ty is an Array, so need to squash
|
38
38
|
tmp_aargs = ActualArguments.new(@lead_tys + [@rest_ty] * n, nil, @kw_tys, @blk_ty)
|
39
|
-
|
40
|
-
|
41
|
-
end
|
39
|
+
subst = tmp_aargs.consistent_with_method_signature?(msig) # XXX: wrong subst handling in the loop!
|
40
|
+
return subst if subst
|
42
41
|
end
|
43
|
-
return
|
42
|
+
return nil
|
44
43
|
end
|
45
44
|
|
45
|
+
subst = {}
|
46
46
|
if msig.rest_ty
|
47
|
-
return
|
47
|
+
return nil if aargs.size < msig.lead_tys.size + msig.post_tys.size
|
48
48
|
aargs.shift(msig.lead_tys.size).zip(msig.lead_tys) do |aarg, farg|
|
49
|
-
return
|
49
|
+
return nil unless subst2 = Type.match?(aarg, farg)
|
50
|
+
subst = Type.merge_substitution(subst, subst2)
|
50
51
|
end
|
51
52
|
aargs.pop(msig.post_tys.size).zip(msig.post_tys) do |aarg, farg|
|
52
|
-
return
|
53
|
+
return nil unless subst2 = Type.match?(aarg, farg)
|
54
|
+
subst = Type.merge_substitution(subst, subst2)
|
53
55
|
end
|
54
56
|
msig.opt_tys.each do |farg|
|
55
57
|
aarg = aargs.shift
|
56
|
-
return
|
58
|
+
return nil unless subst2 = Type.match?(aarg, farg)
|
59
|
+
subst = Type.merge_substitution(subst, subst2)
|
57
60
|
end
|
58
61
|
aargs.each do |aarg|
|
59
|
-
return
|
62
|
+
return nil unless subst2 = Type.match?(aarg, msig.rest_ty)
|
63
|
+
subst = Type.merge_substitution(subst, subst2)
|
60
64
|
end
|
61
65
|
else
|
62
|
-
return
|
63
|
-
return
|
66
|
+
return nil if aargs.size < msig.lead_tys.size + msig.post_tys.size
|
67
|
+
return nil if aargs.size > msig.lead_tys.size + msig.post_tys.size + msig.opt_tys.size
|
64
68
|
aargs.shift(msig.lead_tys.size).zip(msig.lead_tys) do |aarg, farg|
|
65
|
-
return
|
69
|
+
return nil unless subst2 = Type.match?(aarg, farg)
|
70
|
+
subst = Type.merge_substitution(subst, subst2)
|
66
71
|
end
|
67
72
|
aargs.pop(msig.post_tys.size).zip(msig.post_tys) do |aarg, farg|
|
68
|
-
return
|
73
|
+
return nil unless subst2 = Type.match?(aarg, farg)
|
74
|
+
subst = Type.merge_substitution(subst, subst2)
|
69
75
|
end
|
70
76
|
aargs.zip(msig.opt_tys) do |aarg, farg|
|
71
|
-
return
|
77
|
+
return nil unless subst2 = Type.match?(aarg, farg)
|
78
|
+
subst = Type.merge_substitution(subst, subst2)
|
72
79
|
end
|
73
80
|
end
|
74
81
|
# XXX: msig.keyword_tys
|
75
82
|
|
76
83
|
case msig.blk_ty
|
77
84
|
when Type::Proc
|
78
|
-
return
|
85
|
+
return nil if @blk_ty == Type.nil
|
79
86
|
when Type.nil
|
80
|
-
return
|
87
|
+
return nil if @blk_ty != Type.nil
|
81
88
|
when Type::Any
|
82
89
|
else
|
83
90
|
raise "unknown type of formal block signature"
|
84
91
|
end
|
85
|
-
|
92
|
+
|
93
|
+
subst
|
86
94
|
end
|
87
95
|
|
88
96
|
def argument_error(given, exp_lower, exp_upper)
|
@@ -345,7 +353,7 @@ module TypeProf
|
|
345
353
|
when kw.size == 2 # optional keyword (default value is a literal)
|
346
354
|
key, default_ty = *kw
|
347
355
|
default_ty = Type.guess_literal_type(default_ty)
|
348
|
-
default_ty = default_ty.
|
356
|
+
default_ty = default_ty.base_type if default_ty.is_a?(Type::Literal)
|
349
357
|
req = false
|
350
358
|
else # optional keyword (default value is an expression)
|
351
359
|
key, = kw
|