typeprof 0.4.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|