typeprof 0.6.1 → 0.7.0

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.
@@ -139,7 +139,7 @@ module TypeProf
139
139
  iseq_methods[method_name] << @scratch.show_method_signature(ctx)
140
140
  end
141
141
  when AttrMethodDef
142
- next if Config.check_dir_filter(mdef.absolute_path) == :exclude
142
+ next if !mdef.absolute_path || Config.check_dir_filter(mdef.absolute_path) == :exclude
143
143
  mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
144
144
  method_name = mid
145
145
  method_name = "self.#{ mid }" if singleton
@@ -168,12 +168,14 @@ module TypeProf
168
168
  next unless var.to_s.start_with?("@")
169
169
  var = "self.#{ var }" if singleton
170
170
  next if attr_methods[[singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]
171
- [var, ty.screen_name(@scratch), entry.rbs_declared]
171
+ next if entry.rbs_declared
172
+ [var, ty.screen_name(@scratch)]
172
173
  end.compact
173
174
 
174
175
  cvars = cvars.map do |var, entry|
175
176
  next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
176
- [var, entry.type.screen_name(@scratch), entry.rbs_declared]
177
+ next if entry.rbs_declared
178
+ [var, entry.type.screen_name(@scratch)]
177
179
  end.compact
178
180
 
179
181
  if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
@@ -277,14 +279,12 @@ module TypeProf
277
279
  output.puts indent + " extend #{ mod }"
278
280
  first = false
279
281
  end
280
- class_data.ivars.each do |var, ty, rbs_declared|
281
- s = rbs_declared ? "# " : " "
282
- output.puts indent + s + "#{ var } : #{ ty }" unless var.start_with?("_")
282
+ class_data.ivars.each do |var, ty|
283
+ output.puts indent + " #{ var } : #{ ty }" unless var.start_with?("_")
283
284
  first = false
284
285
  end
285
- class_data.cvars.each do |var, ty, rbs_declared|
286
- s = rbs_declared ? "# " : " "
287
- output.puts indent + s + "#{ var } : #{ ty }"
286
+ class_data.cvars.each do |var, ty|
287
+ output.puts indent + " #{ var } : #{ ty }"
288
288
  first = false
289
289
  end
290
290
  class_data.attr_methods.each do |(method_name, hidden), (kind, ty)|
@@ -113,6 +113,7 @@ module TypeProf
113
113
  included_modules = []
114
114
  extended_modules = []
115
115
  methods = {}
116
+ attr_methods = {}
116
117
  ivars = {}
117
118
  cvars = {}
118
119
  rbs_sources = {}
@@ -148,15 +149,15 @@ module TypeProf
148
149
  end
149
150
  when RBS::AST::Members::AttrReader
150
151
  ty = conv_type(member.type)
151
- methods[[false, member.name]] = attr_reader_def(ty)
152
+ attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
152
153
  when RBS::AST::Members::AttrWriter
153
154
  ty = conv_type(member.type)
154
- methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
155
+ attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
155
156
  when RBS::AST::Members::AttrAccessor
156
157
  ty = conv_type(member.type)
157
- methods[[false, member.name]] = attr_reader_def(ty)
158
- methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
158
+ attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
159
159
  when RBS::AST::Members::Alias
160
+ # XXX: an alias to attr methods?
160
161
  if member.instance?
161
162
  method_def = methods[[false, member.old_name]]
162
163
  methods[[false, member.new_name]] = method_def if method_def
@@ -212,6 +213,7 @@ module TypeProf
212
213
  included_modules: included_modules,
213
214
  extended_modules: extended_modules,
214
215
  methods: methods,
216
+ attr_methods: attr_methods,
215
217
  ivars: ivars,
216
218
  cvars: cvars,
217
219
  rbs_sources: rbs_sources,
@@ -308,7 +310,7 @@ module TypeProf
308
310
  opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
309
311
  req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
310
312
  rest_kw_ty = func.rest_keywords
311
- raise NotImplementedError if rest_kw_ty # XXX
313
+ rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
312
314
 
313
315
  ret_ty = conv_type(func.return_type)
314
316
 
@@ -325,32 +327,12 @@ module TypeProf
325
327
  }
326
328
  end
327
329
 
328
- def attr_reader_def(ty)
329
- [{
330
- type_params: [],
331
- lead_tys: [],
332
- opt_tys: [],
333
- rest_ty: nil,
334
- req_kw_tys: {},
335
- opt_kw_tys: {},
336
- rest_kw_ty: nil,
337
- blk: nil,
338
- ret_ty: ty,
339
- }]
340
- end
341
-
342
- def attr_writer_def(ty)
343
- [{
344
- type_params: [],
345
- lead_tys: [ty],
346
- opt_tys: [],
347
- rest_ty: nil,
348
- req_kw_tys: {},
349
- opt_kw_tys: {},
350
- rest_kw_ty: nil,
351
- blk: nil,
352
- ret_ty: ty,
353
- }]
330
+ def attr_method_def(kind, name, ty)
331
+ {
332
+ kind: kind,
333
+ ivar: name,
334
+ ty: ty,
335
+ }
354
336
  end
355
337
 
356
338
  def conv_block(rbs_block)
@@ -518,6 +500,7 @@ module TypeProf
518
500
  included_modules = members[:included_modules]
519
501
  extended_modules = members[:extended_modules]
520
502
  methods = members[:methods]
503
+ attr_methods = members[:attr_methods]
521
504
  ivars = members[:ivars]
522
505
  cvars = members[:cvars]
523
506
  rbs_sources = members[:rbs_sources]
@@ -538,6 +521,14 @@ module TypeProf
538
521
  @scratch.add_method(klass, method_name, singleton, mdef)
539
522
  end
540
523
 
524
+ attr_methods.each do |(singleton, method_name), mdef|
525
+ kind = mdef[:kind]
526
+ ivar = mdef[:ivar]
527
+ ty = conv_type(mdef[:ty]).remove_type_vars
528
+ @scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
529
+ @scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
530
+ end
531
+
541
532
  ivars.each do |ivar_name, ty|
542
533
  ty = conv_type(ty).remove_type_vars
543
534
  @scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
@@ -604,7 +595,7 @@ module TypeProf
604
595
  req, lead_tys, opt_tys, ret_ty = blk
605
596
  lead_tys = lead_tys.map {|ty| conv_type(ty) }
606
597
  opt_tys = opt_tys.map {|ty| conv_type(ty) }
607
- msig = MethodSignature.new(lead_tys, opt_tys, nil, nil, nil, nil, nil)
598
+ msig = MethodSignature.new(lead_tys, opt_tys, nil, [], {}, nil, Type.nil)
608
599
  ret_ty = conv_type(ret_ty)
609
600
  ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
610
601
  ret << Type.nil unless req
@@ -4,10 +4,11 @@ module TypeProf
4
4
  end
5
5
 
6
6
  class ISeqMethodDef < MethodDef
7
- def initialize(iseq, cref)
7
+ def initialize(iseq, cref, outer_ep)
8
8
  @iseq = iseq
9
9
  raise if iseq.nil?
10
10
  @cref = cref
11
+ @outer_ep = outer_ep
11
12
  end
12
13
 
13
14
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
@@ -25,7 +26,7 @@ module TypeProf
25
26
  end
26
27
 
27
28
  nctx = Context.new(@iseq, @cref, mid)
28
- callee_ep = ExecutionPoint.new(nctx, 0, nil)
29
+ callee_ep = ExecutionPoint.new(nctx, 0, @outer_ep)
29
30
  nenv = Env.new(StaticEnv.new(recv, blk_ty, false), locals, [], Utils::HashWrapper.new({}))
30
31
  alloc_site = AllocationSite.new(callee_ep)
31
32
  locals.each_with_index do |ty, i|
@@ -44,6 +45,14 @@ module TypeProf
44
45
  end
45
46
 
46
47
  def do_check_send(msig, recv, mid, ep, scratch)
48
+ klass, singleton = recv.method_dispatch_info
49
+ cur_subst = {}
50
+ direct_method = true
51
+ scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
52
+ direct_method &&= direct
53
+ cur_subst = Type.merge_substitution(cur_subst, subst)
54
+ end
55
+
47
56
  lead_num = @iseq.fargs_format[:lead_num] || 0
48
57
  post_num = @iseq.fargs_format[:post_num] || 0
49
58
  rest_start = @iseq.fargs_format[:rest_start]
@@ -67,7 +76,8 @@ module TypeProf
67
76
  post_start = @iseq.fargs_format[:post_start]
68
77
  rest_start = @iseq.fargs_format[:rest_start]
69
78
  kw_start = @iseq.fargs_format[:kwbits]
70
- kw_start -= @iseq.fargs_format[:keyword].size if kw_start
79
+ keyword = @iseq.fargs_format[:keyword]
80
+ kw_start -= keyword.size if kw_start
71
81
  kw_rest = @iseq.fargs_format[:kwrest]
72
82
  block_start = @iseq.fargs_format[:block_start]
73
83
 
@@ -83,12 +93,14 @@ module TypeProf
83
93
  msig.lead_tys.each_with_index do |ty, i|
84
94
  alloc_site2 = alloc_site.add_id(idx += 1)
85
95
  # nenv is top-level, so it is okay to call Type#localize directly
96
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
86
97
  nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
87
98
  nenv = nenv.local_update(i, ty)
88
99
  end
89
100
  if msig.opt_tys
90
101
  msig.opt_tys.each_with_index do |ty, i|
91
102
  alloc_site2 = alloc_site.add_id(idx += 1)
103
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
92
104
  nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
93
105
  nenv = nenv.local_update(lead_num + i, ty)
94
106
  end
@@ -96,19 +108,27 @@ module TypeProf
96
108
  if msig.rest_ty
97
109
  alloc_site2 = alloc_site.add_id(idx += 1)
98
110
  ty = Type::Array.new(Type::Array::Elements.new([], msig.rest_ty), Type::Instance.new(Type::Builtin[:ary]))
111
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
99
112
  nenv, rest_ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
100
113
  nenv = nenv.local_update(rest_start, rest_ty)
101
114
  end
102
115
  if msig.post_tys
103
116
  msig.post_tys.each_with_index do |ty, i|
104
117
  alloc_site2 = alloc_site.add_id(idx += 1)
118
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
105
119
  nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
106
120
  nenv = nenv.local_update(post_start + i, ty)
107
121
  end
108
122
  end
109
123
  if msig.kw_tys
110
- msig.kw_tys.each_with_index do |(_, key, ty), i|
124
+ msig.kw_tys.each do |_, key, ty|
125
+ i = keyword.index(key)
126
+ unless i
127
+ # warn
128
+ next
129
+ end
111
130
  alloc_site2 = alloc_site.add_id(key)
131
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
112
132
  nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
113
133
  nenv = nenv.local_update(kw_start + i, ty)
114
134
  end
@@ -116,6 +136,7 @@ module TypeProf
116
136
  if msig.kw_rest_ty
117
137
  ty = msig.kw_rest_ty
118
138
  alloc_site2 = alloc_site.add_id(:**)
139
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
119
140
  nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
120
141
  nenv = nenv.local_update(kw_rest, ty)
121
142
  end
@@ -171,30 +192,11 @@ module TypeProf
171
192
  def do_send(recv_orig, mid, aargs, caller_ep, caller_env, scratch, &ctn)
172
193
  recv = scratch.globalize_type(recv_orig, caller_env, caller_ep)
173
194
 
174
- tmp_subst = {}
175
- case
176
- when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
177
- tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
178
- tyvars.zip(recv.elems.elems) do |tyvar, elem|
179
- if tmp_subst[tyvar]
180
- tmp_subst[tyvar] = tmp_subst[tyvar].union(elem)
181
- else
182
- tmp_subst[tyvar] = elem
183
- end
184
- end
185
- when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
186
- tmp_subst = { Type::Var.new(:Elem) => recv.elems.squash }
187
- when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
188
- tyvar_k = Type::Var.new(:K)
189
- tyvar_v = Type::Var.new(:V)
190
- k_ty0, v_ty0 = recv.elems.squash
191
- # XXX: need to heuristically replace ret type Hash[K, V] with self, instead of conversative type?
192
- tmp_subst = { tyvar_k => k_ty0, tyvar_v => v_ty0 }
193
- end
194
-
195
195
  klass, singleton = recv_orig.method_dispatch_info
196
196
  cur_subst = {}
197
- scratch.generate_substitution(klass, singleton, mid, self, tmp_subst) do |subst|
197
+ direct_method = true
198
+ scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
199
+ direct_method &&= direct
198
200
  cur_subst = Type.merge_substitution(cur_subst, subst)
199
201
  end
200
202
 
@@ -206,45 +208,15 @@ module TypeProf
206
208
  # XXX: support self type in msig
207
209
  subst = aargs.consistent_with_method_signature?(msig)
208
210
  next unless subst
209
- case
210
- when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
211
- tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
212
- # XXX: This should be skipped when the called methods belongs to superclass
213
- tyvars.each_with_index do |tyvar, idx|
214
- ty = subst[tyvar]
215
- if ty
216
- ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
217
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
218
- elems.update(idx, ty)
219
- end
220
- end
221
- end
222
- when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
223
- tyvar_elem = Type::Var.new(:Elem)
224
- if subst[tyvar_elem]
225
- ty = subst[tyvar_elem]
226
- ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
227
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
228
- elems.update(nil, ty)
229
- end
230
- end
231
- when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
232
- tyvar_k = Type::Var.new(:K)
233
- tyvar_v = Type::Var.new(:V)
234
- if subst[tyvar_k] && subst[tyvar_v]
235
- k_ty = subst[tyvar_k]
236
- v_ty = subst[tyvar_v]
237
- alloc_site = AllocationSite.new(caller_ep)
238
- ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
239
- ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
240
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
241
- elems.update(k_ty, v_ty)
242
- end
243
- end
211
+
212
+ if direct_method && recv_orig.is_a?(Type::Local)
213
+ ncaller_env = recv_orig.update_container_elem_type(subst, ncaller_env, caller_ep, scratch)
244
214
  end
215
+
245
216
  subst = Type.merge_substitution(subst, cur_subst)
246
217
  # need to check self tyvar?
247
218
  subst[Type::Var.new(:self)] = recv
219
+
248
220
  found = true
249
221
  if aargs.blk_ty.is_a?(Type::Proc)
250
222
  #raise NotImplementedError unless aargs.blk_ty.block_body.is_a?(ISeqBlock) # XXX
@@ -255,88 +227,30 @@ module TypeProf
255
227
  dummy_env = Env.new(StaticEnv.new(s_recv, msig.blk_ty, false), [], [], Utils::HashWrapper.new({}))
256
228
  if msig.blk_ty.is_a?(Type::Proc)
257
229
  scratch.add_callsite!(dummy_ctx, caller_ep, ncaller_env, &ctn)
258
- nfargs = msig.blk_ty.block_body.msig
230
+ bsig = msig.blk_ty.block_body.msig
259
231
  alloc_site = AllocationSite.new(caller_ep).add_id(self)
260
- nlead_tys = (nfargs.lead_tys + nfargs.opt_tys).map.with_index do |ty, i|
261
- if recv.is_a?(Type::Array)
262
- tyvar_elem = Type::Var.new(:Elem)
263
- ty = ty.substitute(subst.merge({ tyvar_elem => recv.elems.squash_or_any }), Config.options[:type_depth_limit])
264
- else
265
- ty = ty.substitute(subst, Config.options[:type_depth_limit])
266
- end
267
- ty = ty.remove_type_vars
268
- alloc_site2 = alloc_site.add_id(i)
269
- dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site2)
232
+ nlead_tys = (bsig.lead_tys + bsig.opt_tys).map.with_index do |ty, i|
233
+ ty = ty.substitute(subst, Config.options[:type_depth_limit]).remove_type_vars
234
+ dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site.add_id(i))
270
235
  ty
271
236
  end
272
- 0.upto(nfargs.opt_tys.size) do |n|
273
- naargs = ActualArguments.new(nlead_tys[0, nfargs.lead_tys.size + n], nil, {}, Type.nil) # XXX: support block to block?
237
+ 0.upto(bsig.opt_tys.size) do |n|
238
+ naargs = ActualArguments.new(nlead_tys[0, bsig.lead_tys.size + n], nil, {}, Type.nil) # XXX: support block to block?
274
239
  scratch.do_invoke_block(aargs.blk_ty, naargs, dummy_ep, dummy_env) do |blk_ret_ty, _ep, _env|
275
240
  subst2 = Type.match?(blk_ret_ty, msig.blk_ty.block_body.ret_ty)
276
241
  if subst2
277
242
  subst2 = Type.merge_substitution(subst, subst2)
278
- case
279
- when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
280
- tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
281
- tyvars.each_with_index do |tyvar, idx|
282
- ty = subst2[tyvar]
283
- if ty
284
- ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
285
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
286
- elems.update(idx, ty)
287
- end
288
- scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
289
- end
290
- end
291
- tyvars.zip(recv.elems.elems) do |tyvar, elem|
292
- if subst2[tyvar]
293
- subst2[tyvar] = subst2[tyvar].union(elem)
294
- else
295
- subst2[tyvar] = elem
296
- end
297
- end
298
- ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
299
- when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
300
- tyvar_elem = Type::Var.new(:Elem)
301
- if subst2[tyvar_elem]
302
- ty = subst2[tyvar_elem]
303
- ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
304
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
305
- elems.update(nil, ty)
306
- end
307
- scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
308
- end
309
- ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
310
- when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
311
- tyvar_k = Type::Var.new(:K)
312
- tyvar_v = Type::Var.new(:V)
313
- k_ty0, v_ty0 = recv.elems.squash
314
- if subst2[tyvar_k] && subst2[tyvar_v]
315
- k_ty = subst2[tyvar_k]
316
- v_ty = subst2[tyvar_v]
317
- k_ty0 = k_ty0.union(k_ty)
318
- v_ty0 = v_ty0.union(v_ty)
319
- alloc_site = AllocationSite.new(caller_ep)
320
- ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
321
- ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
322
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
323
- elems.update(k_ty, v_ty)
324
- end
325
- scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
326
- end
327
- ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
328
- else
329
- ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
243
+ if direct_method && recv_orig.is_a?(Type::Local)
244
+ ncaller_env = recv_orig.update_container_elem_type(subst2, ncaller_env, caller_ep, scratch)
245
+ scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
330
246
  end
247
+ ret_ty2 = ret_ty.substitute(subst2, Config.options[:type_depth_limit]).remove_type_vars
331
248
  else
332
- # raise "???"
333
- # XXX: need warning
334
- ret_ty = Type.any
249
+ ret_ty2 = Type.any
335
250
  end
336
- ret_ty = ret_ty.remove_type_vars
337
251
  # XXX: check the return type from the block
338
252
  # sig.blk_ty.block_body.ret_ty.eql?(_ret_ty) ???
339
- scratch.add_return_value!(dummy_ctx, ret_ty)
253
+ scratch.add_return_value!(dummy_ctx, ret_ty2)
340
254
  end
341
255
  # scratch.add_return_value!(dummy_ctx, ret_ty) ?
342
256
  # This makes `def foo; 1.times { return "str" }; end` return Integer|String
@@ -149,6 +149,10 @@ module TypeProf
149
149
  raise "cannot substitute abstract type: #{ self.class }"
150
150
  end
151
151
 
152
+ def generate_substitution
153
+ {}
154
+ end
155
+
152
156
  DummySubstitution = Object.new
153
157
  def DummySubstitution.[](_)
154
158
  Type.any
@@ -203,11 +207,12 @@ module TypeProf
203
207
  local = nil
204
208
  tys.each do |ty|
205
209
  raise ty.inspect unless ty.is_a?(Type)
206
- local = true if ty.is_a?(LocalArray) || ty.is_a?(LocalHash)
210
+ local = true if ty.is_a?(Local)
207
211
  end
208
212
  raise if local && elems
209
213
 
210
214
  @elems = elems
215
+ raise elems.inspect if elems && !elems.is_a?(::Hash)
211
216
  end
212
217
 
213
218
  def each_free_type_variable(&blk)
@@ -285,7 +290,7 @@ module TypeProf
285
290
  types.delete(Type::Instance.new(Type::Builtin[:true]))
286
291
  bool = true
287
292
  end
288
- types.delete(Type.any) unless Config.options[:pedantic_output]
293
+ types.delete(Type.any) unless Config.options[:show_untyped]
289
294
  proc_tys, types = types.partition {|ty| ty.is_a?(Proc) }
290
295
  types = types.map {|ty| ty.screen_name(scratch) }
291
296
  types << scratch.show_proc_signature(proc_tys) unless proc_tys.empty?
@@ -817,6 +822,7 @@ module TypeProf
817
822
  @opt_tys = opt_tys
818
823
  @rest_ty = rest_ty
819
824
  @post_tys = post_tys
825
+ raise unless post_tys
820
826
  @kw_tys = kw_tys
821
827
  kw_tys.each {|a| raise if a.size != 3 } if kw_tys
822
828
  @kw_rest_ty = kw_rest_ty