steep 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/exe/rbs +1 -1
  4. data/lib/steep/annotation_parser.rb +4 -4
  5. data/lib/steep/ast/buffer.rb +11 -7
  6. data/lib/steep/ast/builtin.rb +8 -0
  7. data/lib/steep/ast/types/factory.rb +55 -55
  8. data/lib/steep/drivers/check.rb +20 -4
  9. data/lib/steep/drivers/langserver.rb +6 -1
  10. data/lib/steep/drivers/vendor.rb +2 -2
  11. data/lib/steep/project/completion_provider.rb +5 -11
  12. data/lib/steep/project/dsl.rb +14 -0
  13. data/lib/steep/project/file.rb +42 -46
  14. data/lib/steep/project/hover_content.rb +11 -5
  15. data/lib/steep/project/options.rb +25 -3
  16. data/lib/steep/project/target.rb +10 -4
  17. data/lib/steep/signature/errors.rb +1 -1
  18. data/lib/steep/signature/validator.rb +8 -8
  19. data/lib/steep/source.rb +1 -1
  20. data/lib/steep/type_construction.rb +987 -711
  21. data/lib/steep/type_inference/constant_env.rb +1 -1
  22. data/lib/steep/type_inference/context.rb +7 -3
  23. data/lib/steep/type_inference/context_array.rb +111 -0
  24. data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
  25. data/lib/steep/type_inference/logic.rb +130 -0
  26. data/lib/steep/type_inference/type_env.rb +5 -69
  27. data/lib/steep/typing.rb +79 -22
  28. data/lib/steep/version.rb +1 -1
  29. data/lib/steep.rb +6 -1
  30. data/smoke/alias/Steepfile +1 -0
  31. data/smoke/and/Steepfile +1 -0
  32. data/smoke/array/Steepfile +1 -0
  33. data/smoke/array/b.rb +0 -2
  34. data/smoke/block/Steepfile +1 -0
  35. data/smoke/case/Steepfile +1 -0
  36. data/smoke/class/Steepfile +1 -0
  37. data/smoke/const/Steepfile +1 -0
  38. data/smoke/dstr/Steepfile +1 -0
  39. data/smoke/ensure/Steepfile +1 -0
  40. data/smoke/enumerator/Steepfile +1 -0
  41. data/smoke/extension/Steepfile +1 -0
  42. data/smoke/extension/c.rb +1 -0
  43. data/smoke/hash/Steepfile +1 -0
  44. data/smoke/hello/Steepfile +1 -0
  45. data/smoke/if/Steepfile +1 -0
  46. data/smoke/if/a.rb +1 -1
  47. data/smoke/implements/Steepfile +1 -0
  48. data/smoke/initialize/Steepfile +1 -0
  49. data/smoke/integer/Steepfile +1 -0
  50. data/smoke/interface/Steepfile +1 -0
  51. data/smoke/kwbegin/Steepfile +1 -0
  52. data/smoke/lambda/Steepfile +1 -0
  53. data/smoke/literal/Steepfile +1 -0
  54. data/smoke/map/Steepfile +1 -0
  55. data/smoke/method/Steepfile +1 -0
  56. data/smoke/module/Steepfile +1 -0
  57. data/smoke/regexp/Steepfile +1 -0
  58. data/smoke/regression/Steepfile +1 -0
  59. data/smoke/rescue/Steepfile +1 -0
  60. data/smoke/rescue/a.rb +1 -1
  61. data/smoke/self/Steepfile +1 -0
  62. data/smoke/skip/Steepfile +1 -0
  63. data/smoke/stdout/Steepfile +1 -0
  64. data/smoke/super/Steepfile +1 -0
  65. data/smoke/type_case/Steepfile +1 -0
  66. data/smoke/yield/Steepfile +1 -0
  67. data/steep.gemspec +1 -1
  68. data/vendor/ruby-signature/.gitignore +2 -2
  69. data/vendor/ruby-signature/README.md +2 -2
  70. data/vendor/ruby-signature/Rakefile +2 -2
  71. data/vendor/ruby-signature/bin/annotate-with-rdoc +14 -13
  72. data/vendor/ruby-signature/bin/console +1 -1
  73. data/vendor/ruby-signature/bin/sort +7 -6
  74. data/vendor/ruby-signature/bin/test_runner.rb +0 -1
  75. data/vendor/ruby-signature/docs/CONTRIBUTING.md +1 -1
  76. data/vendor/ruby-signature/docs/sigs.md +3 -3
  77. data/vendor/ruby-signature/docs/stdlib.md +1 -1
  78. data/vendor/ruby-signature/docs/syntax.md +9 -9
  79. data/vendor/ruby-signature/exe/rbs +5 -1
  80. data/vendor/ruby-signature/lib/rbs/ast/annotation.rb +27 -0
  81. data/vendor/ruby-signature/lib/rbs/ast/comment.rb +27 -0
  82. data/vendor/ruby-signature/lib/rbs/ast/declarations.rb +395 -0
  83. data/vendor/ruby-signature/lib/rbs/ast/members.rb +362 -0
  84. data/vendor/ruby-signature/lib/rbs/buffer.rb +50 -0
  85. data/vendor/ruby-signature/lib/rbs/builtin_names.rb +55 -0
  86. data/vendor/ruby-signature/lib/rbs/cli.rb +558 -0
  87. data/vendor/ruby-signature/lib/rbs/constant.rb +26 -0
  88. data/vendor/ruby-signature/lib/rbs/constant_table.rb +150 -0
  89. data/vendor/ruby-signature/lib/rbs/definition.rb +170 -0
  90. data/vendor/ruby-signature/lib/rbs/definition_builder.rb +919 -0
  91. data/vendor/ruby-signature/lib/rbs/environment.rb +281 -0
  92. data/vendor/ruby-signature/lib/rbs/environment_loader.rb +136 -0
  93. data/vendor/ruby-signature/lib/rbs/environment_walker.rb +124 -0
  94. data/vendor/ruby-signature/lib/rbs/errors.rb +187 -0
  95. data/vendor/ruby-signature/lib/rbs/location.rb +102 -0
  96. data/vendor/ruby-signature/lib/rbs/method_type.rb +123 -0
  97. data/vendor/ruby-signature/lib/rbs/namespace.rb +91 -0
  98. data/vendor/ruby-signature/lib/{ruby/signature → rbs}/parser.rb +21 -23
  99. data/vendor/ruby-signature/lib/{ruby/signature → rbs}/parser.y +18 -18
  100. data/vendor/ruby-signature/lib/rbs/prototype/rb.rb +553 -0
  101. data/vendor/ruby-signature/lib/rbs/prototype/rbi.rb +587 -0
  102. data/vendor/ruby-signature/lib/rbs/prototype/runtime.rb +381 -0
  103. data/vendor/ruby-signature/lib/rbs/substitution.rb +46 -0
  104. data/vendor/ruby-signature/lib/rbs/test/errors.rb +61 -0
  105. data/vendor/ruby-signature/lib/rbs/test/hook.rb +294 -0
  106. data/vendor/ruby-signature/lib/{ruby/signature → rbs}/test/setup.rb +7 -7
  107. data/vendor/ruby-signature/lib/rbs/test/spy.rb +325 -0
  108. data/vendor/ruby-signature/lib/rbs/test/test_helper.rb +183 -0
  109. data/vendor/ruby-signature/lib/rbs/test/type_check.rb +254 -0
  110. data/vendor/ruby-signature/lib/rbs/test.rb +26 -0
  111. data/vendor/ruby-signature/lib/rbs/type_name.rb +70 -0
  112. data/vendor/ruby-signature/lib/rbs/types.rb +936 -0
  113. data/vendor/ruby-signature/lib/rbs/variance_calculator.rb +138 -0
  114. data/vendor/ruby-signature/lib/rbs/vendorer.rb +47 -0
  115. data/vendor/ruby-signature/lib/rbs/version.rb +3 -0
  116. data/vendor/ruby-signature/lib/rbs/writer.rb +269 -0
  117. data/vendor/ruby-signature/lib/rbs.rb +64 -0
  118. data/vendor/ruby-signature/lib/ruby/signature.rb +4 -61
  119. data/vendor/ruby-signature/{ruby-signature.gemspec → rbs.gemspec} +4 -4
  120. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +58 -1
  121. data/vendor/ruby-signature/stdlib/base64/base64.rbs +69 -13
  122. data/vendor/ruby-signature/stdlib/benchmark/benchmark.rbs +372 -0
  123. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +9 -0
  124. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +1 -7
  125. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +2 -1
  126. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +3 -2
  127. data/vendor/ruby-signature/stdlib/builtin/file.rbs +902 -302
  128. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +190 -68
  129. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +3 -6
  130. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +6 -4
  131. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +146 -120
  132. data/vendor/ruby-signature/stdlib/builtin/math.rbs +310 -7
  133. data/vendor/ruby-signature/stdlib/builtin/method.rbs +11 -8
  134. data/vendor/ruby-signature/stdlib/builtin/module.rbs +959 -103
  135. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +3 -0
  136. data/vendor/ruby-signature/stdlib/builtin/process.rbs +981 -108
  137. data/vendor/ruby-signature/stdlib/builtin/random.rbs +215 -41
  138. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +47 -0
  139. data/vendor/ruby-signature/stdlib/builtin/string.rbs +9 -2
  140. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +282 -11
  141. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +11 -13
  142. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +25 -29
  143. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +1 -1
  144. data/vendor/ruby-signature/stdlib/builtin/time.rbs +875 -567
  145. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +243 -44
  146. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +103 -109
  147. data/vendor/ruby-signature/stdlib/coverage/coverage.rbs +62 -0
  148. data/vendor/ruby-signature/stdlib/csv/csv.rbs +773 -0
  149. data/vendor/ruby-signature/stdlib/erb/erb.rbs +375 -1
  150. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -4
  151. data/vendor/ruby-signature/stdlib/ipaddr/ipaddr.rbs +247 -0
  152. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +1088 -16
  153. data/vendor/ruby-signature/stdlib/set/set.rbs +251 -27
  154. metadata +49 -44
  155. data/exe/ruby-signature +0 -3
  156. data/vendor/ruby-signature/exe/ruby-signature +0 -7
  157. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
  158. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
  159. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
  160. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
  161. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
  162. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
  163. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -555
  164. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
  165. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
  166. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
  167. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
  168. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
  169. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
  170. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
  171. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
  172. data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
  173. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
  174. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
  175. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -444
  176. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
  177. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
  178. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
  179. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
  180. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
  181. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -327
  182. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
  183. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
  184. data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
  185. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
  186. data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
  187. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
  188. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
  189. data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
  190. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
@@ -1,5 +1,38 @@
1
1
  module Steep
2
2
  class TypeConstruction
3
+ class Pair
4
+ attr_reader :type
5
+ attr_reader :constr
6
+
7
+ def initialize(type:, constr:)
8
+ @type = type
9
+ @constr = constr
10
+ end
11
+
12
+ def with(type: self.type, constr: self.constr)
13
+ self.class.new(
14
+ type: type,
15
+ constr: constr
16
+ )
17
+ end
18
+
19
+ def +(other)
20
+ if type.is_a?(AST::Types::Bot)
21
+ other.with(type: type)
22
+ else
23
+ other
24
+ end
25
+ end
26
+
27
+ def context
28
+ constr.context
29
+ end
30
+
31
+ def to_ary
32
+ [type, constr, context]
33
+ end
34
+ end
35
+
3
36
  attr_reader :checker
4
37
  attr_reader :source
5
38
  attr_reader :annotations
@@ -50,6 +83,36 @@ module Steep
50
83
  )
51
84
  end
52
85
 
86
+ def with_updated_context(lvar_env: self.context.lvar_env)
87
+ if lvar_env != self.context.lvar_env
88
+ with(context: self.context.with(lvar_env: lvar_env))
89
+ else
90
+ self
91
+ end
92
+ end
93
+
94
+ def with(annotations: self.annotations, context: self.context, typing: self.typing)
95
+ if context != self.context || typing != self.typing
96
+ self.class.new(
97
+ checker: checker,
98
+ source: source,
99
+ annotations: annotations,
100
+ typing: typing,
101
+ context: context
102
+ )
103
+ else
104
+ self
105
+ end
106
+ end
107
+
108
+ def update_context()
109
+ with(context: yield(self.context))
110
+ end
111
+
112
+ def update_lvar_env
113
+ with_updated_context(lvar_env: yield(context.lvar_env))
114
+ end
115
+
53
116
  def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
54
117
  checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
55
118
  end
@@ -100,7 +163,7 @@ module Steep
100
163
  else
101
164
  method_type.block.type
102
165
  end
103
- var_types[block_arg.children[0].name] = block_type
166
+ var_types[block_arg.children[0]] = block_type
104
167
  end
105
168
  end
106
169
 
@@ -123,12 +186,6 @@ module Steep
123
186
  super_method: super_method
124
187
  )
125
188
 
126
- if var_types
127
- var_types.each do |name, type|
128
- type_env.set(lvar: name, type: type)
129
- end
130
- end
131
-
132
189
  if definition
133
190
  definition.instance_variables.each do |name, decl|
134
191
  type_env.set(ivar: name, type: checker.factory.type(decl.type))
@@ -136,12 +193,27 @@ module Steep
136
193
  end
137
194
 
138
195
  type_env = type_env.with_annotations(
139
- lvar_types: annots.lvar_types,
140
196
  ivar_types: annots.ivar_types,
141
197
  const_types: annots.const_types,
142
198
  self_type: annots.self_type || self_type
143
199
  )
144
200
 
201
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
202
+ subtyping: checker,
203
+ self_type: annots.self_type || self_type
204
+ )
205
+
206
+ if var_types
207
+ lvar_env = lvar_env.update(
208
+ assigned_types: var_types.each.with_object({}) {|(var, type), hash|
209
+ arg_node = args.find {|arg| arg.children[0] == var }
210
+ hash[var.name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type, nodes: [arg_node].compact)
211
+ }
212
+ )
213
+ end
214
+
215
+ lvar_env = lvar_env.annotate(annots)
216
+
145
217
  self.class.new(
146
218
  checker: checker,
147
219
  source: source,
@@ -152,7 +224,8 @@ module Steep
152
224
  block_context: nil,
153
225
  break_context: nil,
154
226
  self_type: annots.self_type || self_type,
155
- type_env: type_env
227
+ type_env: type_env,
228
+ lvar_env: lvar_env
156
229
  ),
157
230
  typing: typing,
158
231
  )
@@ -242,6 +315,11 @@ module Steep
242
315
  const_env: module_const_env,
243
316
  signatures: checker.factory.env)
244
317
 
318
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
319
+ subtyping: checker,
320
+ self_type: module_context_.module_type
321
+ ).annotate(annots)
322
+
245
323
  self.class.new(
246
324
  checker: checker,
247
325
  source: source,
@@ -253,7 +331,8 @@ module Steep
253
331
  break_context: nil,
254
332
  module_context: module_context_,
255
333
  self_type: module_context_.module_type,
256
- type_env: module_type_env
334
+ type_env: module_type_env,
335
+ lvar_env: lvar_env
257
336
  )
258
337
  )
259
338
  end
@@ -341,51 +420,90 @@ module Steep
341
420
  const_env: class_const_env,
342
421
  signatures: checker.factory.env)
343
422
 
423
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
424
+ subtyping: checker,
425
+ self_type: module_context.module_type
426
+ ).annotate(annots)
427
+
428
+ class_body_context = TypeInference::Context.new(
429
+ method_context: nil,
430
+ block_context: nil,
431
+ module_context: module_context,
432
+ break_context: nil,
433
+ self_type: module_context.module_type,
434
+ type_env: class_type_env,
435
+ lvar_env: lvar_env
436
+ )
344
437
 
345
438
  self.class.new(
346
439
  checker: checker,
347
440
  source: source,
348
441
  annotations: annots,
349
442
  typing: typing,
350
- context: TypeInference::Context.new(
351
- method_context: nil,
352
- block_context: nil,
353
- module_context: module_context,
354
- break_context: nil,
355
- self_type: module_context.module_type,
356
- type_env: class_type_env
357
- )
443
+ context: class_body_context
358
444
  )
359
445
  end
360
446
 
361
447
  def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
362
448
  annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
363
449
 
364
- lvar_types = self.type_env.lvar_types.each.with_object({}) do |(var, type), env|
365
- if truthy_vars.member?(var)
366
- env[var] = unwrap(type)
367
- else
368
- env[var] = type
450
+ lvar_env = context.lvar_env
451
+
452
+ unless truthy_vars.empty?
453
+ lvar_env = lvar_env.yield_self do |env|
454
+ decls = env.declared_types.each.with_object({}) do |(name, entry), hash|
455
+ if truthy_vars.include?(name)
456
+ hash[name] = entry.update(type: unwrap(entry.type))
457
+ else
458
+ hash[name] = entry
459
+ end
460
+ end
461
+
462
+ assignments = env.assigned_types.each.with_object({}) do |(name, entry), hash|
463
+ if truthy_vars.include?(name)
464
+ hash[name] = entry.update(type: unwrap(entry.type))
465
+ else
466
+ hash[name] = entry
467
+ end
468
+ end
469
+
470
+ env.update(declared_types: decls, assigned_types: assignments)
369
471
  end
370
472
  end
371
473
 
372
- type_env = self.type_env.with_annotations(lvar_types: lvar_types, self_type: self_type) do |var, relation, result|
373
- raise "Unexpected annotate failure: #{relation}"
474
+ if type_case_override
475
+ lvar_env = type_case_override.inject(lvar_env) do |lvar_env, (name, type)|
476
+ lvar_env.assign!(name, node: node, type: type) do |declared_type, assigned_type, result|
477
+ relation = Subtyping::Relation.new(sub_type: assigned_type, super_type: declared_type)
478
+ typing.add_error(
479
+ Errors::IncompatibleTypeCase.new(
480
+ node: node,
481
+ var_name: name,
482
+ relation: relation,
483
+ result: result
484
+ )
485
+ )
486
+ end
487
+ end
374
488
  end
375
489
 
376
- if type_case_override
377
- type_env = type_env.with_annotations(lvar_types: type_case_override, self_type: self_type) do |var, relation, result|
378
- typing.add_error(
379
- Errors::IncompatibleTypeCase.new(node: node,
490
+ lvar_env = lvar_env.annotate(annots) do |var, outer_type, inner_type, result|
491
+ relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
492
+ typing.add_error(
493
+ Errors::IncompatibleAnnotation.new(node: node,
380
494
  var_name: var,
381
495
  relation: relation,
382
496
  result: result)
383
- )
384
- end
497
+ )
498
+ end
499
+
500
+ type_env = context.type_env
501
+
502
+ if type_case_override
503
+ type_env = type_env.with_annotations(self_type: self_type)
385
504
  end
386
505
 
387
506
  type_env = type_env.with_annotations(
388
- lvar_types: annots.lvar_types,
389
507
  ivar_types: annots.ivar_types,
390
508
  const_types: annots.const_types,
391
509
  gvar_types: {},
@@ -399,19 +517,18 @@ module Steep
399
517
  )
400
518
  end
401
519
 
402
- with(context: context.with(type_env: type_env, break_context: break_context))
520
+ update_context {|context|
521
+ context.with(type_env: type_env,
522
+ break_context: break_context,
523
+ lvar_env: lvar_env)
524
+ }
403
525
  end
404
526
 
405
- NOTHING = ::Object.new
527
+ def add_typing(node, type:, constr: self)
528
+ raise if constr.typing != self.typing
406
529
 
407
- def with(annotations: NOTHING, context: NOTHING)
408
- self.class.new(
409
- checker: checker,
410
- source: source,
411
- annotations: annotations.equal?(NOTHING) ? self.annotations : annotations,
412
- typing: typing,
413
- context: context.equal?(NOTHING) ? self.context : context
414
- )
530
+ typing.add_typing(node, type, nil)
531
+ Pair.new(type: type, constr: constr)
415
532
  end
416
533
 
417
534
  def synthesize(node, hint: nil)
@@ -420,43 +537,63 @@ module Steep
420
537
  case node.type
421
538
  when :begin, :kwbegin
422
539
  yield_self do
540
+ end_pos = node.loc.expression.end_pos
541
+
423
542
  *mid_nodes, last_node = each_child_node(node).to_a
424
- mid_nodes.each do |child|
425
- synthesize(child)
426
- end
427
543
  if last_node
428
- type = synthesize(last_node, hint: hint)
544
+ pair = mid_nodes.inject(Pair.new(type: AST::Builtin.nil_type, constr: self)) do |pair, node|
545
+ pair.constr.synthesize(node).yield_self {|p| pair + p }.tap do |new_pair|
546
+ if new_pair.constr.context != pair.constr.context
547
+ # update context
548
+ range = node.loc.expression.end_pos..end_pos
549
+ typing.add_context(range, context: new_pair.constr.context)
550
+ end
551
+ end
552
+ end
553
+
554
+ p = pair.constr.synthesize(last_node, hint: hint)
555
+ last_pair = pair + p
556
+ last_pair.constr.add_typing(node, type: last_pair.type, constr: last_pair.constr)
429
557
  else
430
- type = AST::Builtin.nil_type
558
+ add_typing(node, type: AST::Builtin.nil_type)
431
559
  end
432
-
433
- typing.add_typing(node, type, context)
434
560
  end
435
561
 
436
562
  when :lvasgn
437
563
  yield_self do
438
- var = node.children[0]
439
- rhs = node.children[1]
564
+ var, rhs = node.children
565
+ name = var.name
440
566
 
441
- case var.name
567
+ case name
442
568
  when :_, :__any__
443
- synthesize(rhs, hint: AST::Builtin.any_type)
444
- typing.add_typing(node, AST::Builtin.any_type, context)
569
+ synthesize(rhs, hint: AST::Builtin.any_type).yield_self do |pair|
570
+ add_typing(node, type: AST::Builtin.any_type, constr: pair.constr)
571
+ end
445
572
  when :__skip__
446
- typing.add_typing(node, AST::Builtin.any_type, context)
573
+ add_typing(node, type: AST::Builtin.any_type)
447
574
  else
448
- type_assignment(var, rhs, node, hint: hint)
575
+ rhs_result = synthesize(rhs, hint: hint || context.lvar_env.declared_types[name]&.type)
576
+ constr = rhs_result.constr.update_lvar_env do |lvar_env|
577
+ lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
578
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
579
+ lhs_type: declared_type,
580
+ rhs_type: actual_type,
581
+ result: result))
582
+ end
583
+ end
584
+
585
+ add_typing(node, type: rhs_result.type, constr: constr)
449
586
  end
450
587
  end
451
588
 
452
589
  when :lvar
453
590
  yield_self do
454
591
  var = node.children[0]
455
- type = type_env.get(lvar: var.name) do
456
- fallback_to_any node
592
+ if (type = context.lvar_env[var.name])
593
+ add_typing node, type: type
594
+ else
595
+ fallback_to_any(node)
457
596
  end
458
-
459
- typing.add_typing node, type, context
460
597
  end
461
598
 
462
599
  when :ivasgn
@@ -471,7 +608,7 @@ module Steep
471
608
  type = type_env.get(ivar: name) do
472
609
  fallback_to_any node
473
610
  end
474
- typing.add_typing(node, type, context)
611
+ add_typing(node, type: type)
475
612
  end
476
613
 
477
614
  when :send
@@ -484,7 +621,7 @@ module Steep
484
621
  module_type
485
622
  end
486
623
 
487
- typing.add_typing(node, type, context)
624
+ add_typing(node, type: type)
488
625
  else
489
626
  type_send(node, send_node: node, block_params: nil, block_body: nil)
490
627
  end
@@ -492,83 +629,58 @@ module Steep
492
629
 
493
630
  when :csend
494
631
  yield_self do
495
- type = if self_class?(node)
632
+ pair = if self_class?(node)
496
633
  module_type = expand_alias(module_context.module_type)
497
634
  type = if module_type.is_a?(AST::Types::Name::Class)
498
635
  AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
499
636
  else
500
637
  module_type
501
638
  end
502
- typing.add_typing(node, type, context)
639
+ add_typing(node, type: type)
503
640
  else
504
641
  type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true)
505
642
  end
506
643
 
507
- union_type(type, AST::Builtin.nil_type)
644
+ lvar_env = context.lvar_env.join(pair.context.lvar_env, context.lvar_env)
645
+ add_typing(node,
646
+ type: union_type(pair.type, AST::Builtin.nil_type),
647
+ constr: pair.constr.with_updated_context(lvar_env: lvar_env))
508
648
  end
509
649
 
510
650
  when :match_with_lvasgn
511
651
  each_child_node(node) do |child|
512
652
  synthesize(child)
513
653
  end
514
- typing.add_typing(node, AST::Builtin.any_type, context)
654
+ add_typing(node, type: AST::Builtin.any_type)
515
655
 
516
656
  when :op_asgn
517
657
  yield_self do
518
658
  lhs, op, rhs = node.children
519
659
 
520
- synthesize(rhs)
660
+ case lhs.type
661
+ when :lvasgn
662
+ var_node = lhs.updated(:lvar)
663
+ send_node = rhs.updated(:send, [var_node, op, rhs])
664
+ new_node = node.updated(:lvasgn, [lhs.children[0], send_node])
521
665
 
522
- lhs_type = case lhs.type
523
- when :lvasgn
524
- type_env.get(lvar: lhs.children.first.name) do
525
- break
526
- end
527
- when :ivasgn
528
- type_env.get(ivar: lhs.children.first) do
529
- break
530
- end
531
- else
532
- Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
533
- nil
534
- end
666
+ type, constr = synthesize(new_node, hint: hint)
535
667
 
536
- case
537
- when lhs_type == AST::Builtin.any_type
538
- typing.add_typing(node, lhs_type, context)
539
- when !lhs_type
540
- fallback_to_any(node)
541
- else
542
- lhs_interface = checker.factory.interface(lhs_type, private: false)
543
- op_method = lhs_interface.methods[op]
668
+ constr.add_typing(node, type: type)
544
669
 
545
- if op_method
546
- args = TypeInference::SendArgs.from_nodes([rhs])
547
- return_type, _ = type_method_call(node,
548
- receiver_type: lhs_type,
549
- method_name: op,
550
- method: op_method,
551
- args: args,
552
- block_params: nil,
553
- block_body: nil,
554
- topdown_hint: true)
670
+ when :ivasgn
671
+ var_node = lhs.updated(:ivar)
672
+ send_node = rhs.updated(:send, [var_node, op, rhs])
673
+ new_node = node.updated(:ivasgn, [lhs.children[0], send_node])
555
674
 
556
- result = check_relation(sub_type: return_type, super_type: lhs_type)
557
- if result.failure?
558
- typing.add_error(
559
- Errors::IncompatibleAssignment.new(
560
- node: node,
561
- lhs_type: lhs_type,
562
- rhs_type: return_type,
563
- result: result
564
- )
565
- )
566
- end
567
- else
568
- typing.add_error Errors::NoMethod.new(node: node, method: op, type: expand_self(lhs_type))
569
- end
675
+ type, constr = synthesize(new_node, hint: hint)
676
+
677
+ constr.add_typing(node, type: type)
678
+
679
+ else
680
+ Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
570
681
 
571
- typing.add_typing(node, lhs_type, context)
682
+ _, constr = synthesize(rhs)
683
+ constr.add_typing(node, type: AST::Builtin.any_type)
572
684
  end
573
685
  end
574
686
 
@@ -597,7 +709,7 @@ module Steep
597
709
  block_body: nil,
598
710
  topdown_hint: true)
599
711
 
600
- typing.add_typing node, return_type, context
712
+ add_typing node, type: return_type
601
713
  else
602
714
  fallback_to_any node do
603
715
  Errors::UnexpectedSuper.new(node: node, method: method_context.name)
@@ -619,49 +731,64 @@ module Steep
619
731
  end
620
732
 
621
733
  when :def
622
- new = for_new_method(node.children[0],
623
- node,
624
- args: node.children[1].children,
625
- self_type: module_context&.instance_type,
626
- definition: module_context&.instance_definition)
627
-
628
- each_child_node(node.children[1]) do |arg|
629
- new.synthesize(arg)
630
- end
631
-
632
- if node.children[2]
633
- return_type = expand_alias(new.method_context&.return_type)
634
- if return_type && !return_type.is_a?(AST::Types::Void)
635
- new.check(node.children[2], return_type) do |_, actual_type, result|
636
- typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
637
- expected: new.method_context&.return_type,
638
- actual: actual_type,
639
- result: result))
640
- end
641
- else
642
- new.synthesize(node.children[2])
734
+ yield_self do
735
+ name, args_node, body_node = node.children
736
+
737
+ new = for_new_method(name,
738
+ node,
739
+ args: args_node.children,
740
+ self_type: module_context&.instance_type,
741
+ definition: module_context&.instance_definition)
742
+ new.typing.add_context_for_node(node, context: new.context)
743
+ new.typing.add_context_for_body(node, context: new.context)
744
+
745
+ each_child_node(args_node) do |arg|
746
+ new.synthesize(arg)
643
747
  end
644
- else
645
- return_type = expand_alias(new.method_context&.return_type)
646
- if return_type && !return_type.is_a?(AST::Types::Void)
647
- result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
648
- if result.failure?
649
- typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
650
- expected: new.method_context&.return_type,
651
- actual: AST::Builtin.nil_type,
652
- result: result))
653
- end
748
+
749
+ body_pair = if body_node
750
+ return_type = expand_alias(new.method_context&.return_type)
751
+ if return_type && !return_type.is_a?(AST::Types::Void)
752
+ new.check(body_node, return_type) do |_, actual_type, result|
753
+ typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
754
+ expected: new.method_context&.return_type,
755
+ actual: actual_type,
756
+ result: result))
757
+ end
758
+ else
759
+ new.synthesize(body_node)
760
+ end
761
+ else
762
+ return_type = expand_alias(new.method_context&.return_type)
763
+ if return_type && !return_type.is_a?(AST::Types::Void)
764
+ result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
765
+ if result.failure?
766
+ typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
767
+ expected: new.method_context&.return_type,
768
+ actual: AST::Builtin.nil_type,
769
+ result: result))
770
+ end
771
+ end
772
+
773
+ Pair.new(type: AST::Builtin.nil_type, constr: new)
774
+ end
775
+
776
+ if body_node
777
+ begin_pos = body_node.loc.expression.end_pos
778
+ end_pos = node.loc.end.begin_pos
779
+
780
+ typing.add_context(begin_pos..end_pos, context: body_pair.context)
654
781
  end
655
- end
656
782
 
657
- if module_context
658
- module_context.defined_instance_methods << node.children[0]
659
- end
783
+ if module_context
784
+ module_context.defined_instance_methods << node.children[0]
785
+ end
660
786
 
661
- typing.add_typing(node, AST::Builtin.any_type, new.context)
787
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
788
+ end
662
789
 
663
790
  when :defs
664
- synthesize(node.children[0]).tap do |self_type|
791
+ synthesize(node.children[0]).type.tap do |self_type|
665
792
  self_type = expand_self(self_type)
666
793
  definition = case self_type
667
794
  when AST::Types::Name::Instance
@@ -677,6 +804,8 @@ module Steep
677
804
  args: node.children[2].children,
678
805
  self_type: self_type,
679
806
  definition: definition)
807
+ new.typing.add_context_for_node(node, context: new.context)
808
+ new.typing.add_context_for_body(node, context: new.context)
680
809
 
681
810
  each_child_node(node.children[2]) do |arg|
682
811
  new.synthesize(arg)
@@ -703,7 +832,7 @@ module Steep
703
832
  end
704
833
  end
705
834
 
706
- typing.add_typing(node, AST::Builtin::Symbol.instance_type, context)
835
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
707
836
 
708
837
  when :return
709
838
  yield_self do
@@ -716,7 +845,7 @@ module Steep
716
845
  nil
717
846
  else
718
847
  method_return_type
719
- end)
848
+ end).type
720
849
  end
721
850
 
722
851
  value_type = if return_types.size == 1
@@ -739,7 +868,7 @@ module Steep
739
868
  end
740
869
  end
741
870
 
742
- typing.add_typing(node, AST::Builtin.any_type, context)
871
+ add_typing(node, type: AST::Builtin.bottom_type)
743
872
  end
744
873
 
745
874
  when :break
@@ -765,7 +894,7 @@ module Steep
765
894
  typing.add_error Errors::UnexpectedJump.new(node: node)
766
895
  end
767
896
 
768
- typing.add_typing(node, AST::Builtin.any_type, context)
897
+ add_typing(node, type: AST::Builtin.bottom_type)
769
898
 
770
899
  when :next
771
900
  value = node.children[0]
@@ -790,77 +919,99 @@ module Steep
790
919
  typing.add_error Errors::UnexpectedJump.new(node: node)
791
920
  end
792
921
 
793
- typing.add_typing(node, AST::Builtin.any_type, context)
922
+ add_typing(node, type: AST::Builtin.bottom_type)
794
923
 
795
924
  when :retry
796
925
  unless break_context
797
926
  typing.add_error Errors::UnexpectedJump.new(node: node)
798
927
  end
799
- typing.add_typing(node, AST::Builtin.any_type, context)
928
+ add_typing(node, type: AST::Builtin.bottom_type)
800
929
 
801
930
  when :arg, :kwarg, :procarg0
802
931
  yield_self do
803
932
  var = node.children[0]
804
- type = type_env.get(lvar: var.name) do
805
- fallback_to_any node
933
+ type = context.lvar_env[var.name]
934
+ unless type
935
+ type = AST::Builtin.any_type
936
+ Steep.logger.error { "Unknown arg type: #{node}" }
806
937
  end
807
- typing.add_typing(node, type, context)
938
+ add_typing(node, type: type)
808
939
  end
809
940
 
810
941
  when :optarg, :kwoptarg
811
942
  yield_self do
812
943
  var = node.children[0]
813
944
  rhs = node.children[1]
814
- type_assignment(var, rhs, node, hint: hint)
945
+
946
+ type = context.lvar_env[var.name]
947
+
948
+ node_type, constr = synthesize(rhs, hint: type)
949
+
950
+ constr_ = constr.update_lvar_env do |env|
951
+ env.assign(var.name, node: node, type: node_type) do |declared_type, type, result|
952
+ typing.add_error(
953
+ Errors::IncompatibleAssignment.new(node: node,
954
+ lhs_type: declared_type,
955
+ rhs_type: type,
956
+ result: result)
957
+ )
958
+ end
959
+ end
960
+
961
+ add_typing(node, type: constr_.context.lvar_env[var.name], constr: constr_)
815
962
  end
816
963
 
817
964
  when :restarg
818
965
  yield_self do
819
966
  var = node.children[0]
820
- type = type_env.get(lvar: var.name) do
967
+ type = context.lvar_env[var.name]
968
+ unless type
969
+ Steep.logger.error { "Unknown variable: #{node}" }
821
970
  typing.add_error Errors::FallbackAny.new(node: node)
822
- AST::Builtin::Array.instance_type(AST::Builtin.any_type)
971
+ type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
823
972
  end
824
973
 
825
- typing.add_typing(node, type, context)
974
+ add_typing(node, type: type)
826
975
  end
827
976
 
828
977
  when :kwrestarg
829
978
  yield_self do
830
979
  var = node.children[0]
831
- type = type_env.get(lvar: var.name) do
980
+ type = context.lvar_env[var.name]
981
+ unless type
982
+ Steep.logger.error { "Unknown variable: #{node}" }
832
983
  typing.add_error Errors::FallbackAny.new(node: node)
833
- AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
984
+ type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
834
985
  end
835
986
 
836
- typing.add_typing(node, type, context)
987
+ add_typing(node, type: type)
837
988
  end
838
989
 
839
990
  when :float
840
- typing.add_typing(node, AST::Builtin::Float.instance_type, context)
991
+ add_typing(node, type: AST::Builtin::Float.instance_type)
841
992
 
842
993
  when :nil
843
- typing.add_typing(node, AST::Builtin.nil_type, context)
994
+ add_typing(node, type: AST::Builtin.nil_type)
844
995
 
845
996
  when :int
846
997
  yield_self do
847
- literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
998
+ literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_) }
848
999
 
849
1000
  if literal_type
850
- typing.add_typing(node, literal_type, context)
1001
+ add_typing(node, type: literal_type)
851
1002
  else
852
- typing.add_typing(node, AST::Builtin::Integer.instance_type, context)
1003
+ add_typing(node, type: AST::Builtin::Integer.instance_type)
853
1004
  end
854
1005
  end
855
1006
 
856
1007
  when :sym
857
1008
  yield_self do
858
- literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
1009
+ literal_type = expand_alias(hint) {|hint| test_literal_type(node.children[0], hint) }
859
1010
 
860
1011
  if literal_type
861
- typing.add_typing(node, literal_type, context)
1012
+ add_typing(node, type: literal_type)
862
1013
  else
863
- typing.add_typing(node, AST::Builtin::Symbol.instance_type, context)
1014
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
864
1015
  end
865
1016
  end
866
1017
 
@@ -869,14 +1020,14 @@ module Steep
869
1020
  literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
870
1021
 
871
1022
  if literal_type
872
- typing.add_typing(node, literal_type, context)
1023
+ add_typing(node, type: literal_type)
873
1024
  else
874
- typing.add_typing(node, AST::Builtin::String.instance_type, context)
1025
+ add_typing(node, type: AST::Builtin::String.instance_type)
875
1026
  end
876
1027
  end
877
1028
 
878
1029
  when :true, :false
879
- typing.add_typing(node, AST::Types::Boolean.new, context)
1030
+ add_typing(node, type: AST::Types::Boolean.new)
880
1031
 
881
1032
  when :hash
882
1033
  yield_self do
@@ -894,14 +1045,14 @@ module Steep
894
1045
  case child.type
895
1046
  when :pair
896
1047
  key, value = child.children
897
- key_types << synthesize(key).yield_self do |type|
1048
+ key_types << synthesize(key).type.yield_self do |type|
898
1049
  select_super_type(type, key_hint)
899
1050
  end
900
- value_types << synthesize(value).yield_self do |type|
1051
+ value_types << synthesize(value).type.yield_self do |type|
901
1052
  select_super_type(type, value_hint)
902
1053
  end
903
1054
  when :kwsplat
904
- expand_alias(synthesize(child.children[0])) do |splat_type, original_type|
1055
+ expand_alias(synthesize(child.children[0]).type) do |splat_type, original_type|
905
1056
  if AST::Builtin::Hash.instance_type?(splat_type)
906
1057
  key_types << splat_type.args[0]
907
1058
  value_types << splat_type.args[1]
@@ -923,7 +1074,7 @@ module Steep
923
1074
  typing.add_error Errors::FallbackAny.new(node: node)
924
1075
  end
925
1076
 
926
- typing.add_typing(node, AST::Builtin::Hash.instance_type(key_type, value_type), context)
1077
+ add_typing(node, type: AST::Builtin::Hash.instance_type(key_type, value_type))
927
1078
  end
928
1079
 
929
1080
  when :dstr, :xstr
@@ -931,43 +1082,49 @@ module Steep
931
1082
  synthesize(child)
932
1083
  end
933
1084
 
934
- typing.add_typing(node, AST::Builtin::String.instance_type, context)
1085
+ add_typing(node, type: AST::Builtin::String.instance_type)
935
1086
 
936
1087
  when :dsym
937
1088
  each_child_node(node) do |child|
938
1089
  synthesize(child)
939
1090
  end
940
1091
 
941
- typing.add_typing(node, AST::Builtin::Symbol.instance_type, context)
1092
+ add_typing(node, type: AST::Builtin::Symbol.instance_type)
942
1093
 
943
1094
  when :class
944
1095
  yield_self do
945
1096
  for_class(node).tap do |constructor|
1097
+ constructor.typing.add_context_for_node(node, context: constructor.context)
1098
+ constructor.typing.add_context_for_body(node, context: constructor.context)
1099
+
946
1100
  constructor.synthesize(node.children[2]) if node.children[2]
947
1101
 
948
1102
  if constructor.module_context&.implement_name && !namespace_module?(node)
949
1103
  constructor.validate_method_definitions(node, constructor.module_context.implement_name)
950
1104
  end
951
-
952
- typing.add_typing(node, AST::Builtin.nil_type, constructor.context)
953
1105
  end
1106
+
1107
+ add_typing(node, type: AST::Builtin.nil_type)
954
1108
  end
955
1109
 
956
1110
  when :module
957
1111
  yield_self do
958
1112
  for_module(node).yield_self do |constructor|
1113
+ constructor.typing.add_context_for_node(node, context: constructor.context)
1114
+ constructor.typing.add_context_for_body(node, context: constructor.context)
1115
+
959
1116
  constructor.synthesize(node.children[1]) if node.children[1]
960
1117
 
961
1118
  if constructor.module_context&.implement_name && !namespace_module?(node)
962
1119
  constructor.validate_method_definitions(node, constructor.module_context.implement_name)
963
1120
  end
964
-
965
- typing.add_typing(node, AST::Builtin.nil_type, constructor.context)
966
1121
  end
1122
+
1123
+ add_typing(node, type: AST::Builtin.nil_type)
967
1124
  end
968
1125
 
969
1126
  when :self
970
- typing.add_typing node, AST::Types::Self.new, context
1127
+ add_typing node, type: AST::Types::Self.new
971
1128
 
972
1129
  when :const
973
1130
  const_name = Names::Module.from_node(node)
@@ -975,7 +1132,7 @@ module Steep
975
1132
  type = type_env.get(const: const_name) do
976
1133
  fallback_to_any node
977
1134
  end
978
- typing.add_typing node, type, context
1135
+ add_typing node, type: type
979
1136
  else
980
1137
  fallback_to_any node
981
1138
  end
@@ -984,7 +1141,7 @@ module Steep
984
1141
  yield_self do
985
1142
  const_name = Names::Module.from_node(node)
986
1143
  if const_name
987
- value_type = synthesize(node.children.last)
1144
+ value_type = synthesize(node.children.last).type
988
1145
  type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
989
1146
  case error
990
1147
  when Subtyping::Result::Failure
@@ -998,9 +1155,9 @@ module Steep
998
1155
  end
999
1156
  end
1000
1157
 
1001
- typing.add_typing(node, type, context)
1158
+ add_typing(node, type: type)
1002
1159
  else
1003
- synthesize(node.children.last)
1160
+ synthesize(node.children.last).type
1004
1161
  fallback_to_any(node)
1005
1162
  end
1006
1163
  end
@@ -1020,7 +1177,7 @@ module Steep
1020
1177
  end
1021
1178
  end
1022
1179
 
1023
- typing.add_typing(node, block_type.type.return_type, context)
1180
+ add_typing(node, type: block_type.type.return_type)
1024
1181
  else
1025
1182
  typing.add_error(Errors::UnexpectedYield.new(node: node))
1026
1183
  fallback_to_any node
@@ -1034,16 +1191,9 @@ module Steep
1034
1191
  if method_context&.method
1035
1192
  if method_context.super_method
1036
1193
  types = method_context.super_method.method_types.map {|method_type|
1037
- case method_type
1038
- when Ruby::Signature::MethodType
1039
- checker.factory.method_type(method_type, self_type: self_type).return_type
1040
- when :any
1041
- AST::Builtin.any_type
1042
- else
1043
- raise "Unexpected method_type: #{method_type.inspect}"
1044
- end
1194
+ checker.factory.method_type(method_type, self_type: self_type).return_type
1045
1195
  }
1046
- typing.add_typing(node, union_type(*types), context)
1196
+ add_typing(node, type: union_type(*types))
1047
1197
  else
1048
1198
  typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
1049
1199
  fallback_to_any node
@@ -1065,7 +1215,7 @@ module Steep
1065
1215
  end
1066
1216
  end
1067
1217
 
1068
- typing.add_typing(node, array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type), context)
1218
+ add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
1069
1219
  else
1070
1220
  is_tuple = nil
1071
1221
 
@@ -1075,7 +1225,7 @@ module Steep
1075
1225
  is_tuple &&= node.children.size >= hint.types.size
1076
1226
  is_tuple &&= hint.types.map.with_index do |child_type, index|
1077
1227
  child_node = node.children[index]
1078
- [synthesize(child_node, hint: child_type), child_type]
1228
+ [synthesize(child_node, hint: child_type).type, child_type]
1079
1229
  end.all? do |node_type, hint_type|
1080
1230
  result = check_relation(sub_type: node_type, super_type: hint_type)
1081
1231
  result.success?
@@ -1092,7 +1242,7 @@ module Steep
1092
1242
  element_types = node.children.flat_map do |e|
1093
1243
  if e.type == :splat
1094
1244
  Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
1095
- synthesize(e.children.first).yield_self do |type|
1245
+ synthesize(e.children.first).type.yield_self do |type|
1096
1246
  expand_alias(type) do |ty|
1097
1247
  case ty
1098
1248
  when AST::Types::Union
@@ -1112,155 +1262,237 @@ module Steep
1112
1262
  end
1113
1263
  end
1114
1264
  else
1115
- [select_super_type(synthesize(e), element_hint)]
1265
+ [select_super_type(synthesize(e).type, element_hint)]
1116
1266
  end
1117
1267
  end
1118
1268
  array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
1119
1269
  end
1120
1270
 
1121
- typing.add_typing(node, array_type, context)
1271
+ add_typing(node, type: array_type)
1122
1272
  end
1123
1273
  end
1124
1274
 
1125
1275
  when :and
1126
1276
  yield_self do
1127
1277
  left, right = node.children
1128
- left_type = synthesize(left)
1278
+ logic = TypeInference::Logic.new(subtyping: checker)
1279
+ truthy, falsey = logic.nodes(node: left)
1129
1280
 
1130
- truthy_vars = TypeConstruction.truthy_variables(left)
1131
- right_type, right_env = for_branch(right, truthy_vars: truthy_vars).yield_self do |constructor|
1132
- type = constructor.synthesize(right)
1133
- [type, constructor.type_env]
1134
- end
1281
+ left_type, constr = synthesize(left)
1282
+ truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1283
+ falsey_vars: falsey.vars,
1284
+ lvar_env: constr.context.lvar_env)
1135
1285
 
1136
- type_env.join!([right_env, TypeInference::TypeEnv.new(subtyping: checker,
1137
- const_env: nil)])
1286
+ right_type, constr = constr.update_lvar_env { truthy_env }.for_branch(right).synthesize(right)
1138
1287
 
1139
- if left_type.is_a?(AST::Types::Boolean)
1140
- typing.add_typing(node, union_type(left_type, right_type), context)
1141
- else
1142
- typing.add_typing(node, union_type(right_type, AST::Builtin.nil_type), context)
1143
- end
1288
+ type = if left_type.is_a?(AST::Types::Boolean)
1289
+ union_type(left_type, right_type)
1290
+ else
1291
+ union_type(right_type, AST::Builtin.nil_type)
1292
+ end
1293
+
1294
+ add_typing(node,
1295
+ type: type,
1296
+ constr: constr.update_lvar_env do
1297
+ if right_type.is_a?(AST::Types::Bot)
1298
+ falsey_env
1299
+ else
1300
+ context.lvar_env.join(falsey_env, constr.context.lvar_env)
1301
+ end
1302
+ end)
1144
1303
  end
1145
1304
 
1146
1305
  when :or
1147
1306
  yield_self do
1148
- c1, c2 = node.children
1149
- t1 = synthesize(c1, hint: hint)
1150
- t2 = synthesize(c2, hint: unwrap(t1))
1151
- type = union_type(unwrap(t1), t2)
1152
- typing.add_typing(node, type, context)
1307
+ left, right = node.children
1308
+ logic = TypeInference::Logic.new(subtyping: checker)
1309
+ truthy, falsey = logic.nodes(node: left)
1310
+
1311
+ left_type, constr = synthesize(left, hint: hint)
1312
+ truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1313
+ falsey_vars: falsey.vars,
1314
+ lvar_env: constr.context.lvar_env)
1315
+ left_type_t, _ = logic.partition_union(left_type)
1316
+
1317
+ right_type, constr = constr.update_lvar_env { falsey_env }.for_branch(right).synthesize(right, hint: left_type_t)
1318
+
1319
+ type = union_type(left_type_t, right_type)
1320
+
1321
+ add_typing(node,
1322
+ type: type,
1323
+ constr: constr.update_lvar_env do
1324
+ if right_type.is_a?(AST::Types::Bot)
1325
+ truthy_env
1326
+ else
1327
+ context.lvar_env.join(truthy_env, constr.context.lvar_env)
1328
+ end
1329
+ end)
1153
1330
  end
1154
1331
 
1155
1332
  when :if
1156
1333
  cond, true_clause, false_clause = node.children
1157
- synthesize cond
1158
1334
 
1159
- truthy_vars = TypeConstruction.truthy_variables(cond)
1335
+ cond_type, constr = synthesize(cond)
1336
+ logic = TypeInference::Logic.new(subtyping: checker)
1337
+
1338
+ truthys, falseys = logic.nodes(node: cond)
1339
+ truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
1340
+ falsey_vars: falseys.vars,
1341
+ lvar_env: constr.context.lvar_env)
1160
1342
 
1161
1343
  if true_clause
1162
- true_type, true_env = for_branch(true_clause, truthy_vars: truthy_vars).yield_self do |constructor|
1163
- type = constructor.synthesize(true_clause, hint: hint)
1164
- [type, constructor.type_env]
1165
- end
1344
+ true_pair = constr
1345
+ .update_lvar_env { truthy_env }
1346
+ .for_branch(true_clause)
1347
+ .tap {|constr| typing.add_context_for_node(true_clause, context: constr.context) }
1348
+ .synthesize(true_clause, hint: hint)
1166
1349
  end
1350
+
1167
1351
  if false_clause
1168
- false_type, false_env = for_branch(false_clause).yield_self do |constructor|
1169
- type = constructor.synthesize(false_clause, hint: hint)
1170
- [type, constructor.type_env]
1352
+ false_pair = constr
1353
+ .update_lvar_env { falsey_env }
1354
+ .for_branch(false_clause)
1355
+ .tap {|constr| typing.add_context_for_node(false_clause, context: constr.context) }
1356
+ .synthesize(false_clause, hint: hint)
1357
+ end
1358
+
1359
+ constr = constr.update_lvar_env do |env|
1360
+ envs = []
1361
+
1362
+ if true_pair
1363
+ unless true_pair.type.is_a?(AST::Types::Bot)
1364
+ envs << true_pair.context.lvar_env
1365
+ end
1366
+ else
1367
+ envs << truthy_env
1368
+ end
1369
+
1370
+ if false_pair
1371
+ unless false_pair.type.is_a?(AST::Types::Bot)
1372
+ envs << false_pair.context.lvar_env
1373
+ end
1374
+ else
1375
+ envs << falsey_env
1171
1376
  end
1377
+
1378
+ env.join(*envs)
1172
1379
  end
1173
1380
 
1174
- type_env.join!([true_env, false_env].compact)
1175
- typing.add_typing(node, union_type(true_type, false_type), context)
1381
+ add_typing(node,
1382
+ type: union_type(true_pair&.type || AST::Builtin.nil_type,
1383
+ false_pair&.type || AST::Builtin.nil_type),
1384
+ constr: constr)
1176
1385
 
1177
1386
  when :case
1178
1387
  yield_self do
1179
- cond, *whens = node.children
1388
+ cond, *whens, els = node.children
1389
+
1390
+ constr = self
1180
1391
 
1181
1392
  if cond
1182
- cond_type = expand_alias(synthesize(cond))
1393
+ cond_type, constr = synthesize(cond)
1394
+ cond_type = expand_alias(cond_type)
1183
1395
  if cond_type.is_a?(AST::Types::Union)
1184
1396
  var_names = TypeConstruction.value_variables(cond)
1185
1397
  var_types = cond_type.types.dup
1186
1398
  end
1187
1399
  end
1188
1400
 
1189
- pairs = whens.each.with_object([]) do |clause, pairs|
1190
- if clause&.type == :when
1191
- test_types = clause.children.take(clause.children.size - 1).map do |child|
1192
- expand_alias(synthesize(child, hint: hint))
1193
- end
1401
+ branch_pairs = []
1194
1402
 
1195
- if (body = clause.children.last)
1196
- if var_names && var_types && test_types.all? {|type| type.is_a?(AST::Types::Name::Class)}
1197
- var_types_in_body = test_types.flat_map {|test_type|
1198
- filtered_types = var_types.select {|var_type| var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name}
1199
- if filtered_types.empty?
1200
- to_instance_type(test_type)
1201
- else
1202
- filtered_types
1203
- end
1204
- }
1205
- var_types.reject! {|type|
1206
- var_types_in_body.any? {|test_type|
1207
- type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1208
- }
1209
- }
1210
-
1211
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1212
- hash[var_name] = union_type(*var_types_in_body)
1403
+ whens.each do |clause|
1404
+ *tests, body = clause.children
1405
+
1406
+ test_types = []
1407
+ clause_constr = constr
1408
+
1409
+ tests.each do |test|
1410
+ type, clause_constr = synthesize(test)
1411
+ test_types << expand_alias(type)
1412
+ end
1413
+
1414
+ if body
1415
+ if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Class) }
1416
+ var_types_in_body = test_types.flat_map do |test_type|
1417
+ filtered_types = var_types.select do |var_type|
1418
+ var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
1419
+ end
1420
+ if filtered_types.empty?
1421
+ to_instance_type(test_type)
1422
+ else
1423
+ filtered_types
1424
+ end
1425
+ end
1426
+
1427
+ var_types.reject! do |type|
1428
+ var_types_in_body.any? do |test_type|
1429
+ type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1213
1430
  end
1214
- else
1215
- type_case_override = nil
1216
1431
  end
1217
1432
 
1218
- for_branch(body, type_case_override: type_case_override).yield_self do |body_construction|
1219
- type = body_construction.synthesize(body, hint: hint)
1220
- pairs << [type, body_construction.type_env]
1433
+ var_type_in_body = union_type(*var_types_in_body)
1434
+ type_case_override = var_names.each.with_object({}) do |var_name, hash|
1435
+ hash[var_name] = var_type_in_body
1221
1436
  end
1437
+
1438
+ branch_pairs << clause_constr
1439
+ .for_branch(body, type_case_override: type_case_override)
1440
+ .synthesize(body, hint: hint)
1222
1441
  else
1223
- pairs << [AST::Builtin.nil_type, nil]
1442
+ branch_pairs << clause_constr.synthesize(body, hint: hint)
1224
1443
  end
1225
1444
  else
1226
- if clause
1227
- if var_types
1228
- if !var_types.empty?
1229
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1230
- hash[var_name] = union_type(*var_types)
1231
- end
1232
- var_types.clear
1233
- else
1234
- typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1235
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1236
- hash[var_name] = AST::Builtin.any_type
1237
- end
1238
- end
1239
- end
1445
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1446
+ end
1447
+ end
1240
1448
 
1241
- for_branch(clause, type_case_override: type_case_override).yield_self do |body_construction|
1242
- type = body_construction.synthesize(clause, hint: hint)
1243
- pairs << [type, body_construction.type_env]
1244
- end
1449
+ if els
1450
+ if var_names && var_types
1451
+ if var_types.empty?
1452
+ typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1453
+ end
1454
+
1455
+ else_override = var_names.each.with_object({}) do |var_name, hash|
1456
+ hash[var_name] = unless var_types.empty?
1457
+ union_type(*var_types)
1458
+ else
1459
+ AST::Builtin.any_type
1460
+ end
1245
1461
  end
1462
+ branch_pairs << constr
1463
+ .for_branch(els, type_case_override: else_override)
1464
+ .synthesize(els, hint: hint)
1465
+ else
1466
+ branch_pairs << constr.synthesize(els, hint: hint)
1246
1467
  end
1247
1468
  end
1248
1469
 
1249
- types = pairs.map(&:first)
1250
- envs = pairs.map(&:last)
1470
+ types = branch_pairs.map(&:type)
1471
+ constrs = branch_pairs.map(&:constr)
1251
1472
 
1252
- unless var_types&.empty? || whens.last
1473
+ unless var_types&.empty? || els
1253
1474
  types.push AST::Builtin.nil_type
1254
1475
  end
1255
1476
 
1256
- type_env.join!(envs.compact)
1257
- typing.add_typing(node, union_type(*types), context)
1477
+ constr = constr.update_lvar_env do |env|
1478
+ env.join(*constrs.map {|c| c.context.lvar_env })
1479
+ end
1480
+
1481
+ add_typing(node, type: union_type(*types), constr: constr)
1258
1482
  end
1259
1483
 
1260
1484
  when :rescue
1261
1485
  yield_self do
1262
1486
  body, *resbodies, else_node = node.children
1263
- body_type = synthesize(body) if body
1487
+ body_pair = synthesize(body) if body
1488
+
1489
+ body_constr = if body_pair
1490
+ self.update_lvar_env do |env|
1491
+ env.join(env, body_pair.context.lvar_env)
1492
+ end
1493
+ else
1494
+ self
1495
+ end
1264
1496
 
1265
1497
  resbody_pairs = resbodies.map do |resbody|
1266
1498
  exn_classes, assignment, body = resbody.children
@@ -1268,7 +1500,7 @@ module Steep
1268
1500
  if exn_classes
1269
1501
  case exn_classes.type
1270
1502
  when :array
1271
- exn_types = exn_classes.children.map {|child| synthesize(child)}
1503
+ exn_types = exn_classes.children.map {|child| synthesize(child).type }
1272
1504
  else
1273
1505
  Steep.logger.error "Unexpected exception list: #{exn_classes.type}"
1274
1506
  end
@@ -1301,27 +1533,28 @@ module Steep
1301
1533
  type_override[var_name] = AST::Builtin.any_type
1302
1534
  end
1303
1535
 
1304
- resbody_construction = for_branch(resbody, type_case_override: type_override)
1536
+ resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
1305
1537
 
1306
- type = if body
1307
- resbody_construction.synthesize(body)
1308
- else
1309
- AST::Builtin.nil_type
1310
- end
1311
- [type, resbody_construction.type_env]
1538
+ if body
1539
+ resbody_construction.synthesize(body)
1540
+ else
1541
+ Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
1542
+ end
1312
1543
  end
1313
- resbody_types, resbody_envs = resbody_pairs.transpose
1544
+
1545
+ resbody_types = resbody_pairs.map(&:type)
1546
+ resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
1314
1547
 
1315
1548
  if else_node
1316
- else_construction = for_branch(else_node)
1317
- else_type = else_construction.synthesize(else_node)
1318
- else_env = else_construction.type_env
1549
+ else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
1550
+ add_typing(node,
1551
+ type: union_type(*[else_pair.type, *resbody_types].compact),
1552
+ constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
1553
+ else
1554
+ add_typing(node,
1555
+ type: union_type(*[body_pair&.type, *resbody_types].compact),
1556
+ constr: update_lvar_env {|env| env.join(*resbody_envs, (body_pair&.constr || self).context.lvar_env) })
1319
1557
  end
1320
-
1321
- type_env.join!([*resbody_envs, else_env].compact)
1322
-
1323
- types = [body_type, *resbody_types, else_type].compact
1324
- typing.add_typing(node, union_type(*types), context)
1325
1558
  end
1326
1559
 
1327
1560
  when :resbody
@@ -1329,66 +1562,105 @@ module Steep
1329
1562
  klasses, asgn, body = node.children
1330
1563
  synthesize(klasses) if klasses
1331
1564
  synthesize(asgn) if asgn
1332
- body_type = synthesize(body) if body
1333
- typing.add_typing(node, body_type, context)
1565
+ body_type = synthesize(body).type if body
1566
+ add_typing(node, type: body_type)
1334
1567
  end
1335
1568
 
1336
1569
  when :ensure
1337
1570
  yield_self do
1338
1571
  body, ensure_body = node.children
1339
- body_type = synthesize(body) if body
1572
+ body_type = synthesize(body).type if body
1340
1573
  synthesize(ensure_body) if ensure_body
1341
- typing.add_typing(node, union_type(body_type), context)
1574
+ add_typing(node, type: union_type(body_type))
1342
1575
  end
1343
1576
 
1344
1577
  when :masgn
1345
1578
  type_masgn(node)
1346
1579
 
1347
- when :while, :while_post, :until, :until_post
1580
+ when :while, :until
1348
1581
  yield_self do
1349
1582
  cond, body = node.children
1583
+ _, constr = synthesize(cond)
1584
+
1585
+ logic = TypeInference::Logic.new(subtyping: checker)
1586
+ truthy, falsey = logic.nodes(node: cond)
1350
1587
 
1351
- synthesize(cond)
1352
- truthy_vars = node.type == :while ? TypeConstruction.truthy_variables(cond) : Set.new
1588
+ case node.type
1589
+ when :while
1590
+ body_env, exit_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1591
+ when :until
1592
+ exit_env, body_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1593
+ end
1353
1594
 
1354
1595
  if body
1355
- for_loop = for_branch(body,
1356
- truthy_vars: truthy_vars,
1357
- break_context: TypeInference::Context::BreakContext.new(
1358
- break_type: nil,
1359
- next_type: nil
1360
- ))
1361
- for_loop.synthesize(body)
1362
- type_env.join!([for_loop.type_env])
1596
+ _, body_constr = constr
1597
+ .update_lvar_env { body_env.pin_assignments }
1598
+ .for_branch(body,
1599
+ break_context: TypeInference::Context::BreakContext.new(
1600
+ break_type: nil,
1601
+ next_type: nil
1602
+ ))
1603
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1604
+ .synthesize(body)
1605
+
1606
+ constr = constr.update_lvar_env {|env| env.join(exit_env, body_constr.context.lvar_env) }
1607
+ else
1608
+ constr = constr.update_lvar_env { exit_env }
1363
1609
  end
1364
1610
 
1365
- typing.add_typing(node, AST::Builtin.any_type, context)
1611
+ add_typing(node, type: AST::Builtin.nil_type, constr: constr)
1612
+ end
1613
+
1614
+ when :while_post, :until_post
1615
+ yield_self do
1616
+ cond, body = node.children
1617
+
1618
+ cond_pair = synthesize(cond)
1619
+
1620
+ if body
1621
+ for_loop = cond_pair.constr
1622
+ .update_lvar_env {|env| env.pin_assignments }
1623
+ .for_branch(body,
1624
+ break_context: TypeInference::Context::BreakContext.new(
1625
+ break_type: nil,
1626
+ next_type: nil
1627
+ ))
1628
+
1629
+ typing.add_context_for_node(body, context: for_loop.context)
1630
+ body_pair = for_loop.synthesize(body)
1631
+
1632
+ constr = cond_pair.constr.update_lvar_env {|env| env.join(env, body_pair.context.lvar_env) }
1633
+
1634
+ add_typing(node, type: AST::Builtin.nil_type, constr: constr)
1635
+ else
1636
+ add_typing(node, type: AST::Builtin.nil_type, constr: cond_pair.constr)
1637
+ end
1366
1638
  end
1367
1639
 
1368
1640
  when :irange, :erange
1369
- types = node.children.map {|n| synthesize(n)}
1641
+ types = node.children.map {|n| synthesize(n).type }
1370
1642
  type = AST::Builtin::Range.instance_type(union_type(*types))
1371
- typing.add_typing(node, type, context)
1643
+ add_typing(node, type: type)
1372
1644
 
1373
1645
  when :regexp
1374
1646
  each_child_node(node) do |child|
1375
1647
  synthesize(child)
1376
1648
  end
1377
1649
 
1378
- typing.add_typing(node, AST::Builtin::Regexp.instance_type, context)
1650
+ add_typing(node, type: AST::Builtin::Regexp.instance_type)
1379
1651
 
1380
1652
  when :regopt
1381
1653
  # ignore
1382
- typing.add_typing(node, AST::Builtin.any_type, context)
1654
+ add_typing(node, type: AST::Builtin.any_type)
1383
1655
 
1384
1656
  when :nth_ref, :back_ref
1385
- typing.add_typing(node, AST::Builtin::String.instance_type, context)
1657
+ add_typing(node, type: AST::Builtin::String.instance_type)
1386
1658
 
1387
1659
  when :or_asgn, :and_asgn
1388
1660
  yield_self do
1389
1661
  _, rhs = node.children
1390
- rhs_type = synthesize(rhs)
1391
- typing.add_typing(node, rhs_type, context)
1662
+ rhs_type = synthesize(rhs).type
1663
+ add_typing(node, type: rhs_type)
1392
1664
  end
1393
1665
 
1394
1666
  when :defined?
@@ -1396,7 +1668,7 @@ module Steep
1396
1668
  synthesize(child)
1397
1669
  end
1398
1670
 
1399
- typing.add_typing(node, AST::Builtin.any_type, context)
1671
+ add_typing(node, type: AST::Builtin.any_type)
1400
1672
 
1401
1673
  when :gvasgn
1402
1674
  yield_self do
@@ -1422,7 +1694,7 @@ module Steep
1422
1694
  typing.add_error Errors::FallbackAny.new(node: node)
1423
1695
  end
1424
1696
 
1425
- typing.add_typing(node, type, context)
1697
+ add_typing(node, type: type)
1426
1698
  end
1427
1699
 
1428
1700
  when :block_pass
@@ -1450,9 +1722,9 @@ module Steep
1450
1722
  end
1451
1723
  end
1452
1724
 
1453
- type ||= synthesize(node.children[0], hint: hint)
1725
+ type ||= synthesize(node.children[0], hint: hint).type
1454
1726
 
1455
- typing.add_typing node, type, context
1727
+ add_typing node, type: type
1456
1728
  end
1457
1729
 
1458
1730
  when :blockarg
@@ -1461,7 +1733,7 @@ module Steep
1461
1733
  synthesize(child)
1462
1734
  end
1463
1735
 
1464
- typing.add_typing node, AST::Builtin.any_type, context
1736
+ add_typing node, type: AST::Builtin.any_type
1465
1737
  end
1466
1738
 
1467
1739
  when :splat, :sclass, :alias
@@ -1472,55 +1744,35 @@ module Steep
1472
1744
  synthesize(child)
1473
1745
  end
1474
1746
 
1475
- typing.add_typing node, AST::Builtin.any_type, context
1747
+ add_typing node, type: AST::Builtin.any_type
1476
1748
  end
1477
1749
 
1478
1750
  else
1479
1751
  raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
1752
+ end.tap do |pair|
1753
+ unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
1754
+ # Steep.logger.error { "result = #{pair.inspect}" }
1755
+ # Steep.logger.error { "node = #{node.type}" }
1756
+ raise "#synthesize should return an instance of Pair: #{pair.class}"
1757
+ end
1480
1758
  end
1481
1759
  end
1482
1760
  end
1483
1761
 
1484
1762
  def check(node, type, constraints: Subtyping::Constraints.empty)
1485
- type_ = synthesize(node, hint: type)
1763
+ pair = synthesize(node, hint: type)
1486
1764
 
1487
- result = check_relation(sub_type: type_, super_type: type, constraints: constraints)
1765
+ result = check_relation(sub_type: pair.type, super_type: type, constraints: constraints)
1488
1766
  if result.failure?
1489
- yield(type, type_, result)
1490
- end
1491
- end
1492
-
1493
- def type_assignment(var, rhs, node, hint: nil)
1494
- if rhs
1495
- expand_alias(synthesize(rhs, hint: type_env.lvar_types[var.name] || hint)) do |rhs_type|
1496
- node_type = assign_type_to_variable(var, rhs_type, node)
1497
- typing.add_typing(node, node_type, context)
1498
- end
1767
+ yield(type, pair.type, result)
1768
+ pair.with(type: type)
1499
1769
  else
1500
- raise
1501
- lhs_type = variable_type(var)
1502
-
1503
- if lhs_type
1504
- typing.add_typing(node, lhs_type, context)
1505
- else
1506
- fallback_to_any node
1507
- end
1508
- end
1509
- end
1510
-
1511
- def assign_type_to_variable(var, type, node)
1512
- name = var.name
1513
- type_env.assign(lvar: name, type: type, self_type: self_type) do |result|
1514
- var_type = type_env.get(lvar: name)
1515
- typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1516
- lhs_type: var_type,
1517
- rhs_type: type,
1518
- result: result))
1770
+ pair
1519
1771
  end
1520
1772
  end
1521
1773
 
1522
1774
  def type_ivasgn(name, rhs, node)
1523
- rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) })
1775
+ rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) }).type
1524
1776
  ivar_type = type_env.assign(ivar: name, type: rhs_type, self_type: self_type) do |error|
1525
1777
  case error
1526
1778
  when Subtyping::Result::Failure
@@ -1533,102 +1785,111 @@ module Steep
1533
1785
  fallback_to_any node
1534
1786
  end
1535
1787
  end
1536
- typing.add_typing(node, ivar_type, context)
1788
+ add_typing(node, type: ivar_type)
1537
1789
  end
1538
1790
 
1539
1791
  def type_masgn(node)
1540
1792
  lhs, rhs = node.children
1541
- rhs_original = synthesize(rhs)
1542
- rhs_type = expand_alias(rhs_original)
1543
-
1544
- case
1545
- when rhs.type == :array && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn} && lhs.children.size == rhs.children.size
1546
- pairs = lhs.children.zip(rhs.children)
1547
- pairs.each do |(l, r)|
1548
- case
1549
- when l.type == :lvasgn
1550
- type_assignment(l.children.first, r, l)
1551
- when l.type == :ivasgn
1552
- type_ivasgn(l.children.first, r, l)
1553
- end
1554
- end
1793
+ rhs_pair = synthesize(rhs)
1794
+ rhs_type = expand_alias(rhs_pair.type)
1555
1795
 
1556
- typing.add_typing(node, rhs_type, context)
1796
+ constr = rhs_pair.constr
1557
1797
 
1558
- when rhs_type.is_a?(AST::Types::Tuple) && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
1559
- lhs.children.each.with_index do |asgn, index|
1560
- type = rhs_type.types[index]
1561
-
1562
- case
1563
- when asgn.type == :lvasgn && asgn.children[0].name != :_
1564
- type ||= AST::Builtin.nil_type
1565
- type_env.assign(lvar: asgn.children[0].name, type: type, self_type: self_type) do |result|
1566
- var_type = type_env.get(lvar: asgn.children[0].name)
1567
- typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1568
- lhs_type: var_type,
1569
- rhs_type: type,
1570
- result: result))
1571
- end
1572
- when asgn.type == :ivasgn
1573
- type ||= AST::Builtin.nil_type
1574
- type_env.assign(ivar: asgn.children[0], type: type) do |result|
1575
- var_type = type_env.get(ivar: asgn.children[0])
1576
- typing.add_error(Errors::IncompatibleAssignment.new(node: node,
1577
- lhs_type: var_type,
1578
- rhs_type: type,
1579
- result: result))
1798
+ if lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
1799
+ case
1800
+ when rhs.type == :array && lhs.children.size == rhs.children.size
1801
+ # a, @b = x, y
1802
+
1803
+ constr = lhs.children.zip(rhs.children).inject(constr) do |ctr, (lhs, rhs)|
1804
+ case lhs.type
1805
+ when :lvasgn
1806
+ name = lhs.children[0].name
1807
+ type = typing.type_of(node: rhs)
1808
+ env = ctr.context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
1809
+ typing.add_error(
1810
+ Errors::IncompatibleAssignment.new(node: lhs,
1811
+ lhs_type: declared_type,
1812
+ rhs_type: type,
1813
+ result: result)
1814
+ )
1815
+ end
1816
+ add_typing(lhs,
1817
+ type: type,
1818
+ constr: ctr.with_updated_context(lvar_env: env))
1819
+ when :ivasgn
1820
+ type_ivasgn(lhs.children.first, rhs, lhs)
1821
+ constr
1580
1822
  end
1581
1823
  end
1582
- end
1583
1824
 
1584
- typing.add_typing(node, rhs_type, context)
1825
+ add_typing(node, type: rhs_type, constr: constr)
1585
1826
 
1586
- when rhs_type.is_a?(AST::Types::Any)
1587
- fallback_to_any(node)
1827
+ when rhs_type.is_a?(AST::Types::Tuple)
1828
+ # a, @b = tuple
1588
1829
 
1589
- when AST::Builtin::Array.instance_type?(rhs_type)
1590
- element_type = rhs_type.args.first
1830
+ constr = lhs.children.zip(rhs_type.types).inject(constr) do |ctr, (lhs, type)|
1831
+ ty = type || AST::Builtin.nil_type
1591
1832
 
1592
- lhs.children.each do |assignment|
1593
- case assignment.type
1594
- when :lvasgn
1595
- assign_type_to_variable(assignment.children.first, element_type, assignment)
1596
- when :ivasgn
1597
- assignment.children.first.yield_self do |ivar|
1598
- type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
1833
+ case lhs.type
1834
+ when :lvasgn
1835
+ name = lhs.children[0].name
1836
+ env = ctr.context.lvar_env.assign(name, node: node, type: ty) do |declared_type, type, result|
1837
+ typing.add_error(
1838
+ Errors::IncompatibleAssignment.new(node: lhs,
1839
+ lhs_type: declared_type,
1840
+ rhs_type: type,
1841
+ result: result)
1842
+ )
1843
+ end
1844
+ add_typing(lhs,
1845
+ type: ty,
1846
+ constr: ctr.with_updated_context(lvar_env: env)).constr
1847
+ when :ivasgn
1848
+ ivar = lhs.children[0]
1849
+
1850
+ type_env.assign(ivar: ivar, type: ty, self_type: self_type) do |error|
1599
1851
  case error
1600
1852
  when Subtyping::Result::Failure
1601
- type = type_env.get(ivar: ivar)
1602
- typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
1603
- lhs_type: type,
1604
- rhs_type: element_type,
1853
+ ivar_type = type_env.get(ivar: ivar)
1854
+ typing.add_error(Errors::IncompatibleAssignment.new(node: lhs,
1855
+ lhs_type: ivar_type,
1856
+ rhs_type: ty,
1605
1857
  result: error))
1606
1858
  when nil
1607
1859
  fallback_to_any node
1608
1860
  end
1609
1861
  end
1862
+
1863
+ ctr
1610
1864
  end
1611
1865
  end
1612
- end
1613
1866
 
1614
- typing.add_typing node, rhs_type, context
1867
+ add_typing(node, type: rhs_type, constr: constr)
1615
1868
 
1616
- when rhs_type.is_a?(AST::Types::Union) &&
1617
- rhs_type.types.all? {|type| AST::Builtin::Array.instance_type?(type)}
1869
+ when AST::Builtin::Array.instance_type?(rhs_type)
1870
+ element_type = AST::Types::Union.build(types: [rhs_type.args.first, AST::Builtin.nil_type])
1618
1871
 
1619
- types = rhs_type.types.flat_map do |type|
1620
- type.args.first
1621
- end
1872
+ constr = lhs.children.inject(constr) do |ctr, assignment|
1873
+ case assignment.type
1874
+ when :lvasgn
1875
+ name = assignment.children[0].name
1876
+ env = ctr.context.lvar_env.assign(name, node: node, type: element_type) do |declared_type, type, result|
1877
+ typing.add_error(
1878
+ Errors::IncompatibleAssignment.new(node: assignment,
1879
+ lhs_type: declared_type,
1880
+ rhs_type: type,
1881
+ result: result)
1882
+ )
1883
+ end
1622
1884
 
1623
- element_type = AST::Types::Union.build(types: types)
1885
+ add_typing(assignment,
1886
+ type: element_type,
1887
+ constr: ctr.with_updated_context(lvar_env: env)).constr
1624
1888
 
1625
- lhs.children.each do |assignment|
1626
- case assignment.type
1627
- when :lvasgn
1628
- assign_type_to_variable(assignment.children.first, element_type, assignment)
1629
- when :ivasgn
1630
- assignment.children.first.yield_self do |ivar|
1631
- type_env.assign(ivar: ivar, type: element_type) do |error|
1889
+ when :ivasgn
1890
+ ivar = assignment.children[0]
1891
+
1892
+ type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
1632
1893
  case error
1633
1894
  when Subtyping::Result::Failure
1634
1895
  type = type_env.get(ivar: ivar)
@@ -1640,14 +1901,22 @@ module Steep
1640
1901
  fallback_to_any node
1641
1902
  end
1642
1903
  end
1904
+
1905
+ ctr
1643
1906
  end
1644
1907
  end
1645
- end
1646
1908
 
1647
- typing.add_typing node, rhs_type, context
1909
+ add_typing node, type: rhs_type, constr: constr
1910
+
1911
+ when rhs_type.is_a?(AST::Types::Any)
1912
+ fallback_to_any(node)
1648
1913
 
1914
+ else
1915
+ Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
1916
+ fallback_to_any(node)
1917
+ end
1649
1918
  else
1650
- Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
1919
+ Steep.logger.error("Unsupported masgn left hand side")
1651
1920
  fallback_to_any(node)
1652
1921
  end
1653
1922
  end
@@ -1662,7 +1931,8 @@ module Steep
1662
1931
  return_hint = type_hint.return_type
1663
1932
  end
1664
1933
 
1665
- block_type = type_block(block_param_hint: params_hint,
1934
+ block_pair = type_block(node: node,
1935
+ block_param_hint: params_hint,
1666
1936
  block_type_hint: return_hint,
1667
1937
  node_type_hint: nil,
1668
1938
  block_params: params,
@@ -1670,12 +1940,12 @@ module Steep
1670
1940
  block_annotations: block_annotations,
1671
1941
  topdown_hint: true)
1672
1942
 
1673
- typing.add_typing node, block_type, context
1943
+ add_typing node, type: block_pair.type
1674
1944
  end
1675
1945
 
1676
1946
  def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
1677
1947
  receiver, method_name, *arguments = send_node.children
1678
- receiver_type = receiver ? synthesize(receiver) : AST::Types::Self.new
1948
+ receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
1679
1949
 
1680
1950
  if unwrap
1681
1951
  receiver_type = unwrap(receiver_type)
@@ -1683,70 +1953,70 @@ module Steep
1683
1953
 
1684
1954
  receiver_type = expand_alias(receiver_type)
1685
1955
 
1686
- return_type = case receiver_type
1687
- when AST::Types::Any
1688
- typing.add_typing node, AST::Builtin.any_type, context
1689
-
1690
- when nil
1691
- fallback_to_any node
1692
-
1693
- when AST::Types::Void, AST::Types::Bot, AST::Types::Top
1694
- fallback_to_any node do
1695
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1696
- end
1697
-
1698
- else
1699
- case expanded_receiver_type = expand_self(receiver_type)
1700
- when AST::Types::Self
1701
- Steep.logger.error "`self` type cannot be resolved to concrete type"
1702
- fallback_to_any node do
1703
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1704
- end
1705
- else
1706
- begin
1707
- interface = checker.factory.interface(receiver_type,
1708
- private: !receiver,
1709
- self_type: expanded_receiver_type)
1710
-
1711
- method = interface.methods[method_name]
1712
-
1713
- if method
1714
- args = TypeInference::SendArgs.from_nodes(arguments)
1715
- return_type, _ = type_method_call(node,
1716
- method: method,
1717
- method_name: method_name,
1718
- args: args,
1719
- block_params: block_params,
1720
- block_body: block_body,
1721
- receiver_type: receiver_type,
1722
- topdown_hint: true)
1723
-
1724
- typing.add_typing node, return_type, context
1725
- else
1726
- fallback_to_any node do
1727
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
1728
- end
1729
- end
1730
- rescue => exn
1731
- $stderr.puts exn.inspect
1732
- exn.backtrace.each do |t|
1733
- $stderr.puts t
1734
- end
1956
+ pair = case receiver_type
1957
+ when AST::Types::Any
1958
+ add_typing node, type: AST::Builtin.any_type
1959
+
1960
+ when nil
1961
+ fallback_to_any node
1962
+
1963
+ when AST::Types::Void, AST::Types::Bot, AST::Types::Top
1964
+ fallback_to_any node do
1965
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1966
+ end
1967
+
1968
+ else
1969
+ case expanded_receiver_type = expand_self(receiver_type)
1970
+ when AST::Types::Self
1971
+ Steep.logger.error "`self` type cannot be resolved to concrete type"
1972
+ fallback_to_any node do
1973
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
1974
+ end
1975
+ else
1976
+ begin
1977
+ interface = checker.factory.interface(receiver_type,
1978
+ private: !receiver,
1979
+ self_type: expanded_receiver_type)
1980
+
1981
+ method = interface.methods[method_name]
1982
+
1983
+ if method
1984
+ args = TypeInference::SendArgs.from_nodes(arguments)
1985
+ return_type, constr, _ = type_method_call(node,
1986
+ method: method,
1987
+ method_name: method_name,
1988
+ args: args,
1989
+ block_params: block_params,
1990
+ block_body: block_body,
1991
+ receiver_type: receiver_type,
1992
+ topdown_hint: true)
1993
+
1994
+ add_typing node, type: return_type, constr: constr
1995
+ else
1996
+ fallback_to_any node do
1997
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
1998
+ end
1999
+ end
2000
+ rescue => exn
2001
+ $stderr.puts exn.inspect
2002
+ exn.backtrace.each do |t|
2003
+ $stderr.puts t
2004
+ end
1735
2005
 
1736
- fallback_to_any node do
1737
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
1738
- end
1739
- end
1740
- end
1741
- end
2006
+ fallback_to_any node do
2007
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2008
+ end
2009
+ end
2010
+ end
2011
+ end
1742
2012
 
1743
- case return_type
2013
+ case pair.type
1744
2014
  when nil, Errors::Base
1745
2015
  arguments.each do |arg|
1746
2016
  unless typing.has_type?(arg)
1747
2017
  if arg.type == :splat
1748
- type = synthesize(arg.children[0])
1749
- typing.add_typing(arg, AST::Builtin::Array.instance_type(type), context)
2018
+ type = synthesize(arg.children[0]).type
2019
+ add_typing(arg, type: AST::Builtin::Array.instance_type(type))
1750
2020
  else
1751
2021
  synthesize(arg)
1752
2022
  end
@@ -1759,16 +2029,18 @@ module Steep
1759
2029
  params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
1760
2030
  pairs = params.each.map {|param| [param, AST::Builtin.any_type]}
1761
2031
 
1762
- for_block, _ = for_block(block_annotations: block_annotations,
1763
- param_pairs: pairs,
1764
- method_return_type: AST::Builtin.any_type,
1765
- typing: typing)
2032
+ for_block, _ = constr.for_block(block_annotations: block_annotations,
2033
+ param_pairs: pairs,
2034
+ method_return_type: AST::Builtin.any_type,
2035
+ typing: typing)
2036
+
2037
+ for_block.typing.add_context_for_body(node, context: for_block.context)
1766
2038
 
1767
2039
  for_block.synthesize(block_body)
1768
2040
  end
1769
2041
  end
1770
2042
  else
1771
- return_type
2043
+ pair
1772
2044
  end
1773
2045
  end
1774
2046
 
@@ -1789,6 +2061,8 @@ module Steep
1789
2061
  )
1790
2062
  end
1791
2063
 
2064
+ lvar_env = context.lvar_env.pin_assignments.annotate(block_annotations)
2065
+
1792
2066
  return_type = if block_annotations.break_type
1793
2067
  union_type(method_return_type, block_annotations.break_type)
1794
2068
  else
@@ -1816,7 +2090,8 @@ module Steep
1816
2090
  module_context: module_context,
1817
2091
  break_context: break_context,
1818
2092
  self_type: block_annotations.self_type || self_type,
1819
- type_env: block_type_env
2093
+ type_env: block_type_env,
2094
+ lvar_env: lvar_env
1820
2095
  )
1821
2096
  ), return_type]
1822
2097
  end
@@ -1830,70 +2105,72 @@ module Steep
1830
2105
  end
1831
2106
 
1832
2107
  def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
2108
+ node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
2109
+
1833
2110
  case
1834
2111
  when method.union?
1835
2112
  yield_self do
1836
2113
  results = method.types.map do |method|
1837
- typing.new_child do |child_typing|
1838
- type, error = with_new_typing(child_typing).type_method_call(node,
1839
- method_name: method_name,
1840
- receiver_type: receiver_type,
1841
- method: method,
1842
- args: args,
1843
- block_params: block_params,
1844
- block_body: block_body,
1845
- topdown_hint: false)
1846
- [
1847
- type,
1848
- child_typing,
1849
- error
1850
- ]
1851
- end
1852
- end
1853
-
1854
- if (type, typing, error = results.find {|_, _, error| error })
1855
- typing.save!
1856
- [type, error]
2114
+ typing.new_child(node_range) do |child_typing|
2115
+ with_new_typing(child_typing).type_method_call(node,
2116
+ method_name: method_name,
2117
+ receiver_type: receiver_type,
2118
+ method: method,
2119
+ args: args,
2120
+ block_params: block_params,
2121
+ block_body: block_body,
2122
+ topdown_hint: false)
2123
+ end
2124
+ end
2125
+
2126
+ if (type, constr, error = results.find {|_, _, error| error })
2127
+ constr.typing.save!
2128
+ [type,
2129
+ update_lvar_env { constr.context.lvar_env },
2130
+ error]
1857
2131
  else
1858
- _, typing, _ = results.first
1859
- typing.save!
2132
+ types = results.map(&:first)
2133
+
2134
+ _, constr, _ = results.first
2135
+ constr.typing.save!
1860
2136
 
1861
- [union_type(*results.map(&:first)), nil]
2137
+ [union_type(*types),
2138
+ update_lvar_env { constr.context.lvar_env },
2139
+ nil]
1862
2140
  end
1863
2141
  end
1864
2142
 
1865
2143
  when method.intersection?
1866
2144
  yield_self do
1867
2145
  results = method.types.map do |method|
1868
- typing.new_child do |child_typing|
1869
- type, error = with_new_typing(child_typing).type_method_call(node,
1870
- method_name: method_name,
1871
- receiver_type: receiver_type,
1872
- method: method,
1873
- args: args,
1874
- block_params: block_params,
1875
- block_body: block_body,
1876
- topdown_hint: false)
1877
- [
1878
- type,
1879
- child_typing,
1880
- error
1881
- ]
1882
- end
1883
- end
1884
-
1885
- successes = results.select {|_, _, error| !error }
2146
+ typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2147
+ with_new_typing(child_typing).type_method_call(node,
2148
+ method_name: method_name,
2149
+ receiver_type: receiver_type,
2150
+ method: method,
2151
+ args: args,
2152
+ block_params: block_params,
2153
+ block_body: block_body,
2154
+ topdown_hint: false)
2155
+ end
2156
+ end
2157
+
2158
+ successes = results.reject {|_, _, error| error }
1886
2159
  unless successes.empty?
1887
- types = successes.map {|type, typing, _| type }
1888
- typing = successes[0][1]
1889
- typing.save!
2160
+ types = successes.map(&:first)
2161
+ constr = successes[0][1]
2162
+ constr.typing.save!
1890
2163
 
1891
- [AST::Types::Intersection.build(types: types), nil]
2164
+ [AST::Types::Intersection.build(types: types),
2165
+ update_lvar_env { constr.context.lvar_env },
2166
+ nil]
1892
2167
  else
1893
- type, typing, error = results.first
1894
- typing.save!
2168
+ type, constr, error = results.first
2169
+ constr.typing.save!
1895
2170
 
1896
- [type, error]
2171
+ [type,
2172
+ update_lvar_env { constr.context.lvar_env },
2173
+ error]
1897
2174
  end
1898
2175
  end
1899
2176
 
@@ -1901,55 +2178,40 @@ module Steep
1901
2178
  yield_self do
1902
2179
  results = method.types.flat_map do |method_type|
1903
2180
  Steep.logger.tagged method_type.to_s do
1904
- case method_type
1905
- when Interface::MethodType
1906
- zips = args.zips(method_type.params, method_type.block&.type)
1907
-
1908
- zips.map do |arg_pairs|
1909
- typing.new_child do |child_typing|
1910
- result = self.with_new_typing(child_typing).try_method_type(
1911
- node,
1912
- receiver_type: receiver_type,
1913
- method_type: method_type,
1914
- args: args,
1915
- arg_pairs: arg_pairs,
1916
- block_params: block_params,
1917
- block_body: block_body,
1918
- child_typing: child_typing,
1919
- topdown_hint: topdown_hint
1920
- )
1921
-
1922
- [result, child_typing, method_type]
1923
- end
1924
- end
1925
- when :any
1926
- typing.new_child do |child_typing|
1927
- this = self.with_new_typing(child_typing)
1928
-
1929
- args.args.each do |arg|
1930
- this.synthesize(arg)
1931
- end
2181
+ zips = args.zips(method_type.params, method_type.block&.type)
2182
+
2183
+ zips.map do |arg_pairs|
2184
+ typing.new_child(node_range) do |child_typing|
2185
+ ret = self.with_new_typing(child_typing).try_method_type(
2186
+ node,
2187
+ receiver_type: receiver_type,
2188
+ method_type: method_type,
2189
+ args: args,
2190
+ arg_pairs: arg_pairs,
2191
+ block_params: block_params,
2192
+ block_body: block_body,
2193
+ child_typing: child_typing,
2194
+ topdown_hint: topdown_hint
2195
+ )
1932
2196
 
1933
- if block_body
1934
- this.synthesize(block_body)
1935
- end
2197
+ raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
1936
2198
 
1937
- child_typing.add_typing node, AST::Builtin.any_type, context
2199
+ result, constr = ret
1938
2200
 
1939
- [[AST::Builtin.any_type, child_typing, :any]]
2201
+ [result, constr, method_type]
1940
2202
  end
1941
2203
  end
1942
2204
  end
1943
2205
  end
1944
2206
 
1945
2207
  unless results.empty?
1946
- result, call_typing, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2208
+ result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
1947
2209
  else
1948
2210
  method_type = method.types.last
2211
+ constr = self.with_new_typing(typing.new_child(node_range))
1949
2212
  result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
1950
- call_typing = typing.new_child
1951
2213
  end
1952
- call_typing.save!
2214
+ constr.typing.save!
1953
2215
 
1954
2216
  case result
1955
2217
  when Errors::Base
@@ -1969,9 +2231,13 @@ module Steep
1969
2231
  type = AST::Builtin.any_type
1970
2232
  end
1971
2233
 
1972
- [type, result]
2234
+ [type,
2235
+ update_lvar_env { constr.context.lvar_env },
2236
+ result]
1973
2237
  else # Type
1974
- [result, nil]
2238
+ [result,
2239
+ update_lvar_env { constr.context.lvar_env },
2240
+ nil]
1975
2241
  end
1976
2242
  end
1977
2243
  end
@@ -1984,7 +2250,7 @@ module Steep
1984
2250
  when :hash
1985
2251
  keyword_hash_type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type,
1986
2252
  AST::Builtin.any_type)
1987
- typing.add_typing node, keyword_hash_type, context
2253
+ add_typing node, type: keyword_hash_type
1988
2254
 
1989
2255
  given_keys = Set.new()
1990
2256
 
@@ -2008,7 +2274,7 @@ module Steep
2008
2274
  params.rest_keywords
2009
2275
  end
2010
2276
 
2011
- typing.add_typing key_node, AST::Builtin::Symbol.instance_type, context
2277
+ add_typing key_node, type: AST::Builtin::Symbol.instance_type
2012
2278
 
2013
2279
  given_keys << key_symbol
2014
2280
 
@@ -2090,7 +2356,7 @@ module Steep
2090
2356
  hash_type = AST::Types::Record.new(elements: hash_elements)
2091
2357
  end
2092
2358
 
2093
- node_type = synthesize(node, hint: hash_type)
2359
+ node_type = synthesize(node, hint: hash_type).type
2094
2360
 
2095
2361
  check_relation(sub_type: node_type, super_type: hash_type).else do
2096
2362
  return Errors::ArgumentTypeMismatch.new(
@@ -2118,6 +2384,8 @@ module Steep
2118
2384
  context: context
2119
2385
  )
2120
2386
 
2387
+ constr = construction
2388
+
2121
2389
  method_type.instantiate(instantiation).yield_self do |method_type|
2122
2390
  constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
2123
2391
  variance = Subtyping::VariableVariance.from_method_type(method_type)
@@ -2127,23 +2395,20 @@ module Steep
2127
2395
  case pair
2128
2396
  when Array
2129
2397
  (arg_node, param_type) = pair
2130
-
2131
2398
  param_type = param_type.subst(instantiation)
2132
2399
 
2133
- arg_type = if arg_node.type == :splat
2134
- type = construction.synthesize(arg_node.children[0])
2135
- child_typing.add_typing(arg_node, type, context)
2136
- else
2137
- construction.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2138
- end
2400
+ arg_type, constr = if arg_node.type == :splat
2401
+ constr.synthesize(arg_node.children[0])
2402
+ else
2403
+ constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2404
+ end
2139
2405
 
2140
2406
  check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do |result|
2141
- return Errors::ArgumentTypeMismatch.new(
2142
- node: arg_node,
2143
- receiver_type: receiver_type,
2144
- expected: param_type,
2145
- actual: arg_type
2146
- )
2407
+ return [Errors::ArgumentTypeMismatch.new(node: arg_node,
2408
+ receiver_type: receiver_type,
2409
+ expected: param_type,
2410
+ actual: arg_type),
2411
+ constr]
2147
2412
  end
2148
2413
  else
2149
2414
  # keyword
@@ -2153,7 +2418,7 @@ module Steep
2153
2418
  constraints: constraints)
2154
2419
 
2155
2420
  if result.is_a?(Errors::Base)
2156
- return result
2421
+ return [result, constr]
2157
2422
  end
2158
2423
  end
2159
2424
  end
@@ -2168,10 +2433,9 @@ module Steep
2168
2433
  check_relation(sub_type: AST::Types::Proc.new(params: block_param_hint, return_type: AST::Types::Any.new),
2169
2434
  super_type: method_type.block.type,
2170
2435
  constraints: constraints).else do |result|
2171
- return Errors::IncompatibleBlockParameters.new(
2172
- node: node,
2173
- method_type: method_type
2174
- )
2436
+ return [Errors::IncompatibleBlockParameters.new(node: node,
2437
+ method_type: method_type),
2438
+ constr]
2175
2439
  end
2176
2440
  end
2177
2441
 
@@ -2182,50 +2446,53 @@ module Steep
2182
2446
 
2183
2447
  begin
2184
2448
  method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
2185
- block_type = construction.type_block(block_param_hint: method_type.block.type.params,
2186
- block_type_hint: method_type.block.type.return_type,
2187
- node_type_hint: method_type.return_type,
2188
- block_params: block_params_,
2189
- block_body: block_body,
2190
- block_annotations: block_annotations,
2191
- topdown_hint: topdown_hint)
2192
-
2193
- result = check_relation(sub_type: block_type.return_type,
2449
+ type, _ = constr.type_block(node: node,
2450
+ block_param_hint: method_type.block.type.params,
2451
+ block_type_hint: method_type.block.type.return_type,
2452
+ node_type_hint: method_type.return_type,
2453
+ block_params: block_params_,
2454
+ block_body: block_body,
2455
+ block_annotations: block_annotations,
2456
+ topdown_hint: topdown_hint)
2457
+
2458
+ result = check_relation(sub_type: type.return_type,
2194
2459
  super_type: method_type.block.type.return_type,
2195
2460
  constraints: constraints)
2196
2461
 
2197
2462
  case result
2198
2463
  when Subtyping::Result::Success
2199
2464
  method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)).yield_self do |ret_type|
2200
- if block_annotations.break_type
2201
- AST::Types::Union.new(types: [block_annotations.break_type, ret_type])
2202
- else
2203
- ret_type
2204
- end
2465
+ ty = if block_annotations.break_type
2466
+ AST::Types::Union.new(types: [block_annotations.break_type, ret_type])
2467
+ else
2468
+ ret_type
2469
+ end
2470
+ [ty, constr]
2205
2471
  end
2206
2472
 
2207
2473
  when Subtyping::Result::Failure
2208
- Errors::BlockTypeMismatch.new(node: node,
2209
- expected: method_type.block.type,
2210
- actual: block_type,
2211
- result: result)
2474
+ [Errors::BlockTypeMismatch.new(node: node,
2475
+ expected: method_type.block.type,
2476
+ actual: type,
2477
+ result: result),
2478
+ constr]
2212
2479
  end
2213
2480
  end
2214
2481
 
2215
2482
  rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2216
- Errors::UnsatisfiableConstraint.new(node: node,
2217
- method_type: method_type,
2218
- var: exn.var,
2219
- sub_type: exn.sub_type,
2220
- super_type: exn.super_type,
2221
- result: exn.result)
2483
+ [Errors::UnsatisfiableConstraint.new(node: node,
2484
+ method_type: method_type,
2485
+ var: exn.var,
2486
+ sub_type: exn.sub_type,
2487
+ super_type: exn.super_type,
2488
+ result: exn.result),
2489
+ constr]
2222
2490
  end
2223
2491
 
2224
2492
  when method_type.block && args.block_pass_arg
2225
2493
  begin
2226
2494
  method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
2227
- block_type = synthesize(args.block_pass_arg,
2228
- hint: topdown_hint ? method_type.block.type : nil)
2495
+ block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
2229
2496
  result = check_relation(
2230
2497
  sub_type: block_type,
2231
2498
  super_type: method_type.block.yield_self {|expected_block|
@@ -2240,40 +2507,58 @@ module Steep
2240
2507
 
2241
2508
  case result
2242
2509
  when Subtyping::Result::Success
2243
- method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars))
2510
+ [
2511
+ method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)),
2512
+ constr
2513
+ ]
2244
2514
 
2245
2515
  when Subtyping::Result::Failure
2246
- Errors::BlockTypeMismatch.new(node: node,
2247
- expected: method_type.block.type,
2248
- actual: block_type,
2249
- result: result)
2516
+ [
2517
+ Errors::BlockTypeMismatch.new(node: node,
2518
+ expected: method_type.block.type,
2519
+ actual: block_type,
2520
+ result: result),
2521
+ constr
2522
+ ]
2250
2523
  end
2251
2524
  end
2252
2525
 
2253
2526
  rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2254
- Errors::UnsatisfiableConstraint.new(node: node,
2255
- method_type: method_type,
2256
- var: exn.var,
2257
- sub_type: exn.sub_type,
2258
- super_type: exn.super_type,
2259
- result: exn.result)
2527
+ [
2528
+ Errors::UnsatisfiableConstraint.new(node: node,
2529
+ method_type: method_type,
2530
+ var: exn.var,
2531
+ sub_type: exn.sub_type,
2532
+ super_type: exn.super_type,
2533
+ result: exn.result),
2534
+ constr
2535
+ ]
2260
2536
  end
2261
2537
 
2262
2538
  when (!method_type.block || method_type.block.optional?) && !block_params && !block_body && !args.block_pass_arg
2263
2539
  # OK, without block
2264
- method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)).return_type
2540
+ [
2541
+ method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)).return_type,
2542
+ constr
2543
+ ]
2265
2544
 
2266
2545
  when !method_type.block && (block_params || args.block_pass_arg)
2267
- Errors::UnexpectedBlockGiven.new(
2268
- node: node,
2269
- method_type: method_type
2270
- )
2546
+ [
2547
+ Errors::UnexpectedBlockGiven.new(
2548
+ node: node,
2549
+ method_type: method_type
2550
+ ),
2551
+ constr
2552
+ ]
2271
2553
 
2272
2554
  when method_type.block && !method_type.block.optional? && !block_params && !block_body && !args.block_pass_arg
2273
- Errors::RequiredBlockMissing.new(
2274
- node: node,
2275
- method_type: method_type
2276
- )
2555
+ [
2556
+ Errors::RequiredBlockMissing.new(
2557
+ node: node,
2558
+ method_type: method_type
2559
+ ),
2560
+ constr
2561
+ ]
2277
2562
 
2278
2563
  else
2279
2564
  raise "Unexpected case condition"
@@ -2281,7 +2566,7 @@ module Steep
2281
2566
  end
2282
2567
  end
2283
2568
 
2284
- def type_block(block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
2569
+ def type_block(node:, block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
2285
2570
  block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
2286
2571
 
2287
2572
  param_types_hash = {}
@@ -2297,15 +2582,12 @@ module Steep
2297
2582
  end
2298
2583
  end
2299
2584
 
2300
- block_type_env = type_env.dup.tap do |env|
2301
- param_types_hash.each do |name, type|
2302
- env.set(lvar: name, type: type)
2303
- end
2304
-
2305
- block_annotations.lvar_types.each do |name, type|
2306
- env.set(lvar: name, type: type)
2585
+ lvar_env = context.lvar_env.pin_assignments.yield_self do |env|
2586
+ decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2587
+ hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2307
2588
  end
2308
- end
2589
+ env.update(declared_types: env.declared_types.merge(decls))
2590
+ end.annotate(block_annotations)
2309
2591
 
2310
2592
  break_type = if block_annotations.break_type
2311
2593
  union_type(node_type_hint, block_annotations.break_type)
@@ -2334,33 +2616,38 @@ module Steep
2334
2616
  module_context: module_context,
2335
2617
  break_context: break_context,
2336
2618
  self_type: block_annotations.self_type || self_type,
2337
- type_env: block_type_env
2619
+ type_env: type_env.dup,
2620
+ lvar_env: lvar_env
2338
2621
  )
2339
2622
  )
2340
2623
 
2624
+ for_block_body.typing.add_context_for_body(node, context: for_block_body.context)
2625
+
2341
2626
  if block_body
2342
- return_type = if (body_type = block_context.body_type)
2343
- for_block_body.check(block_body, body_type) do |expected, actual, result|
2344
- typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
2345
- expected: expected,
2346
- actual: actual,
2347
- result: result)
2627
+ body_pair = if (body_type = block_context.body_type)
2628
+ for_block_body.check(block_body, body_type) do |expected, actual, result|
2629
+ typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
2630
+ expected: expected,
2631
+ actual: actual,
2632
+ result: result)
2348
2633
 
2349
- end
2350
- body_type
2351
- else
2352
- for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
2353
2634
  end
2635
+ else
2636
+ for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
2637
+ end
2638
+
2639
+ range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
2640
+ typing.add_context(range, context: body_pair.context)
2354
2641
  else
2355
- return_type = AST::Builtin.any_type
2642
+ body_pair = Pair.new(type: AST::Builtin.nil_type, constr: for_block_body)
2356
2643
  end
2357
2644
 
2358
- AST::Types::Proc.new(
2359
- params: block_param_hint || block_params.params_type,
2360
- return_type: return_type
2361
- ).tap do |type|
2362
- Steep.logger.debug "block_type == #{type}"
2363
- end
2645
+ body_pair.with(
2646
+ type: AST::Types::Proc.new(
2647
+ params: block_param_hint || block_params.params_type,
2648
+ return_type: body_pair.type
2649
+ )
2650
+ )
2364
2651
  end
2365
2652
 
2366
2653
  def each_child_node(node)
@@ -2464,6 +2751,7 @@ module Steep
2464
2751
  end
2465
2752
 
2466
2753
  def union_type(*types)
2754
+ raise if types.empty?
2467
2755
  AST::Types::Union.build(types: types)
2468
2756
  end
2469
2757
 
@@ -2552,7 +2840,7 @@ module Steep
2552
2840
  typing.add_error Errors::FallbackAny.new(node: node)
2553
2841
  end
2554
2842
 
2555
- typing.add_typing node, AST::Builtin.any_type, context
2843
+ add_typing node, type: AST::Builtin.any_type
2556
2844
  end
2557
2845
 
2558
2846
  def self_class?(node)
@@ -2598,21 +2886,6 @@ module Steep
2598
2886
  end
2599
2887
  end
2600
2888
 
2601
- def self.truthy_variables(node)
2602
- case node&.type
2603
- when :lvar
2604
- Set.new([node.children.first.name])
2605
- when :lvasgn
2606
- Set.new([node.children.first.name]) + truthy_variables(node.children[1])
2607
- when :and
2608
- truthy_variables(node.children[0]) + truthy_variables(node.children[1])
2609
- when :begin
2610
- truthy_variables(node.children.last)
2611
- else
2612
- Set.new()
2613
- end
2614
- end
2615
-
2616
2889
  def self.value_variables(node)
2617
2890
  case node&.type
2618
2891
  when :lvar
@@ -2692,7 +2965,7 @@ module Steep
2692
2965
  def try_hash_type(node, hint)
2693
2966
  case hint
2694
2967
  when AST::Types::Record
2695
- typing.new_child do |child_typing|
2968
+ typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2696
2969
  new_construction = with_new_typing(child_typing)
2697
2970
  elements = {}
2698
2971
 
@@ -2709,7 +2982,7 @@ module Steep
2709
2982
  end
2710
2983
 
2711
2984
  value_hint = hint.elements[key_value]
2712
- value_type = new_construction.synthesize(value, hint: value_hint)
2985
+ value_type = new_construction.synthesize(value, hint: value_hint).type
2713
2986
 
2714
2987
  if value_hint
2715
2988
  if check_relation(sub_type: value_type, super_type: value_hint).success?
@@ -2726,12 +2999,15 @@ module Steep
2726
2999
  child_typing.save!
2727
3000
 
2728
3001
  hash = AST::Types::Record.new(elements: elements)
2729
- typing.add_typing(node, hash, context)
3002
+ add_typing(node, type: hash)
2730
3003
  end
2731
3004
  when AST::Types::Union
2732
- hint.types.find do |type|
2733
- try_hash_type(node, type)
3005
+ hint.types.each do |type|
3006
+ if pair = try_hash_type(node, type)
3007
+ return pair
3008
+ end
2734
3009
  end
3010
+ nil
2735
3011
  end
2736
3012
  end
2737
3013
  end