steep 0.23.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/bin/smoke_runner.rb +3 -4
  4. data/lib/steep.rb +4 -3
  5. data/lib/steep/annotation_parser.rb +2 -4
  6. data/lib/steep/ast/builtin.rb +11 -21
  7. data/lib/steep/ast/types.rb +5 -3
  8. data/lib/steep/ast/types/any.rb +1 -3
  9. data/lib/steep/ast/types/boolean.rb +1 -3
  10. data/lib/steep/ast/types/bot.rb +1 -3
  11. data/lib/steep/ast/types/class.rb +2 -2
  12. data/lib/steep/ast/types/factory.rb +249 -89
  13. data/lib/steep/ast/types/helper.rb +6 -0
  14. data/lib/steep/ast/types/instance.rb +2 -2
  15. data/lib/steep/ast/types/intersection.rb +20 -13
  16. data/lib/steep/ast/types/literal.rb +1 -3
  17. data/lib/steep/ast/types/logic.rb +63 -0
  18. data/lib/steep/ast/types/name.rb +15 -67
  19. data/lib/steep/ast/types/nil.rb +1 -3
  20. data/lib/steep/ast/types/proc.rb +5 -2
  21. data/lib/steep/ast/types/record.rb +9 -4
  22. data/lib/steep/ast/types/self.rb +1 -1
  23. data/lib/steep/ast/types/top.rb +1 -3
  24. data/lib/steep/ast/types/tuple.rb +5 -3
  25. data/lib/steep/ast/types/union.rb +16 -9
  26. data/lib/steep/ast/types/var.rb +2 -2
  27. data/lib/steep/ast/types/void.rb +1 -3
  28. data/lib/steep/drivers/check.rb +4 -0
  29. data/lib/steep/errors.rb +14 -0
  30. data/lib/steep/interface/interface.rb +5 -62
  31. data/lib/steep/interface/method_type.rb +394 -93
  32. data/lib/steep/interface/substitution.rb +48 -6
  33. data/lib/steep/module_helper.rb +25 -0
  34. data/lib/steep/project/completion_provider.rb +48 -51
  35. data/lib/steep/project/file.rb +3 -3
  36. data/lib/steep/project/hover_content.rb +4 -6
  37. data/lib/steep/project/target.rb +5 -2
  38. data/lib/steep/server/base_worker.rb +5 -3
  39. data/lib/steep/server/code_worker.rb +2 -0
  40. data/lib/steep/server/master.rb +10 -1
  41. data/lib/steep/signature/validator.rb +3 -3
  42. data/lib/steep/source.rb +4 -3
  43. data/lib/steep/subtyping/check.rb +46 -59
  44. data/lib/steep/subtyping/constraints.rb +8 -0
  45. data/lib/steep/type_construction.rb +771 -513
  46. data/lib/steep/type_inference/block_params.rb +5 -0
  47. data/lib/steep/type_inference/constant_env.rb +3 -6
  48. data/lib/steep/type_inference/context.rb +8 -0
  49. data/lib/steep/type_inference/context_array.rb +4 -3
  50. data/lib/steep/type_inference/logic.rb +31 -0
  51. data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
  52. data/lib/steep/type_inference/type_env.rb +2 -2
  53. data/lib/steep/typing.rb +7 -0
  54. data/lib/steep/version.rb +1 -1
  55. data/smoke/alias/a.rb +1 -1
  56. data/smoke/case/a.rb +1 -1
  57. data/smoke/hash/d.rb +1 -1
  58. data/smoke/if/a.rb +1 -1
  59. data/smoke/module/a.rb +1 -1
  60. data/smoke/rescue/a.rb +4 -13
  61. data/smoke/type_case/a.rb +0 -7
  62. data/steep.gemspec +2 -2
  63. metadata +10 -10
  64. data/lib/steep/ast/method_type.rb +0 -126
  65. data/lib/steep/ast/namespace.rb +0 -80
  66. data/lib/steep/names.rb +0 -86
@@ -10,8 +10,7 @@ module Steep
10
10
  end
11
11
 
12
12
  def instance_super_types(type_name, args:)
13
- type_name_1 = factory.type_name_1(type_name)
14
- ancestors = factory.definition_builder.one_instance_ancestors(type_name_1)
13
+ ancestors = factory.definition_builder.one_instance_ancestors(type_name)
15
14
 
16
15
  subst = unless args.empty?
17
16
  args_ = args.map {|type| factory.type_1(type) }
@@ -19,7 +18,7 @@ module Steep
19
18
  end
20
19
 
21
20
  ancestors.each_ancestor.map do |ancestor|
22
- name = factory.type_name(ancestor.name)
21
+ name = ancestor.name
23
22
 
24
23
  case ancestor
25
24
  when RBS::Definition::Ancestor::Instance
@@ -42,9 +41,8 @@ module Steep
42
41
  )
43
42
  end
44
43
  when RBS::Definition::Ancestor::Singleton
45
- AST::Types::Name::Class.new(
44
+ AST::Types::Name::Singleton.new(
46
45
  name: name,
47
- constructor: nil,
48
46
  location: nil
49
47
  )
50
48
  end
@@ -52,11 +50,10 @@ module Steep
52
50
  end
53
51
 
54
52
  def singleton_super_types(type_name)
55
- type_name_1 = factory.type_name_1(type_name)
56
- ancestors = factory.definition_builder.one_singleton_ancestors(type_name_1)
53
+ ancestors = factory.definition_builder.one_singleton_ancestors(type_name)
57
54
 
58
55
  ancestors.each_ancestor.map do |ancestor|
59
- name = factory.type_name(ancestor.name)
56
+ name = ancestor.name
60
57
 
61
58
  case ancestor
62
59
  when RBS::Definition::Ancestor::Instance
@@ -78,9 +75,8 @@ module Steep
78
75
  )
79
76
  end
80
77
  when RBS::Definition::Ancestor::Singleton
81
- AST::Types::Name::Class.new(
78
+ AST::Types::Name::Singleton.new(
82
79
  name: name,
83
- constructor: nil,
84
80
  location: nil
85
81
  )
86
82
  end
@@ -180,6 +176,14 @@ module Steep
180
176
  constraints: constraints
181
177
  )
182
178
 
179
+ when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
180
+ constraints.add(relation.super_type.name, sub_type: relation.sub_type)
181
+ success(constraints: constraints)
182
+
183
+ when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
184
+ constraints.add(relation.sub_type.name, super_type: relation.super_type)
185
+ success(constraints: constraints)
186
+
183
187
  when relation.sub_type.is_a?(AST::Types::Union)
184
188
  results = relation.sub_type.types.map do |sub_type|
185
189
  check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
@@ -232,14 +236,6 @@ module Steep
232
236
  results.find(&:failure?)
233
237
  end
234
238
 
235
- when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
236
- constraints.add(relation.super_type.name, sub_type: relation.sub_type)
237
- success(constraints: constraints)
238
-
239
- when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
240
- constraints.add(relation.sub_type.name, super_type: relation.super_type)
241
- success(constraints: constraints)
242
-
243
239
  when relation.super_type.is_a?(AST::Types::Var) || relation.sub_type.is_a?(AST::Types::Var)
244
240
  failure(error: Result::Failure::UnknownPairError.new(relation: relation),
245
241
  trace: trace)
@@ -266,7 +262,7 @@ module Steep
266
262
  possible_sub_types = case relation.sub_type
267
263
  when AST::Types::Name::Instance
268
264
  instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
269
- when AST::Types::Name::Class
265
+ when AST::Types::Name::Singleton
270
266
  singleton_super_types(relation.sub_type.name)
271
267
  else
272
268
  []
@@ -302,10 +298,9 @@ module Steep
302
298
  when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
303
299
  if relation.sub_type.types.size >= relation.super_type.types.size
304
300
  pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
305
- results = pairs.flat_map do |t1, t2|
301
+ results = pairs.map do |t1, t2|
306
302
  relation = Relation.new(sub_type: t1, super_type: t2)
307
- [check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints),
308
- check(relation.flip, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)]
303
+ check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
309
304
  end
310
305
 
311
306
  if results.all?(&:success?)
@@ -318,16 +313,17 @@ module Steep
318
313
  trace: trace)
319
314
  end
320
315
 
321
- when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Name::Base)
322
- tuple_interface = factory.interface(relation.sub_type, private: false)
323
- type_interface = factory.interface(relation.super_type, private: false)
316
+ when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
317
+ tuple_element_type = AST::Types::Union.build(
318
+ types: relation.sub_type.types,
319
+ location: relation.sub_type.location
320
+ )
324
321
 
325
- check_interface(tuple_interface,
326
- type_interface,
327
- self_type: self_type,
328
- assumption: assumption,
329
- trace: trace,
330
- constraints: constraints)
322
+ check(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]),
323
+ self_type: self_type,
324
+ assumption: assumption,
325
+ trace: trace,
326
+ constraints: constraints)
331
327
 
332
328
  when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
333
329
  if Set.new(relation.sub_type.elements.keys).superset?(Set.new(relation.super_type.elements.keys))
@@ -394,12 +390,12 @@ module Steep
394
390
  end
395
391
 
396
392
  def definition_for_type(type)
397
- type_name = factory.type_name_1(type.name)
393
+ type_name = type.name
398
394
 
399
395
  case type
400
396
  when AST::Types::Name::Instance
401
397
  factory.definition_builder.build_instance(type_name)
402
- when AST::Types::Name::Class
398
+ when AST::Types::Name::Singleton
403
399
  factory.definition_builder.build_singleton(type_name)
404
400
  when AST::Types::Name::Interface
405
401
  factory.definition_builder.build_interface(type_name)
@@ -484,11 +480,7 @@ module Steep
484
480
  if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
485
481
  sub_type.args.zip(super_type.args)
486
482
  end
487
- when sub_type.is_a?(AST::Types::Name::Class) && super_type.is_a?(AST::Types::Name::Class)
488
- if sub_type.name == super_type.name
489
- []
490
- end
491
- when sub_type.is_a?(AST::Types::Name::Module) && super_type.is_a?(AST::Types::Name::Module)
483
+ when sub_type.is_a?(AST::Types::Name::Singleton) && super_type.is_a?(AST::Types::Name::Singleton)
492
484
  if sub_type.name == super_type.name
493
485
  []
494
486
  end
@@ -535,29 +527,24 @@ module Steep
535
527
 
536
528
  def check_method(name, sub_method, super_method, self_type:, assumption:, trace:, constraints:)
537
529
  trace.method name, sub_method, super_method do
538
- case
539
- when sub_method.overload? && super_method.overload?
540
- super_method.types.map do |super_type|
541
- sub_method.types.map do |sub_type|
542
- check_generic_method_type name,
543
- sub_type,
544
- super_type,
545
- self_type: self_type,
546
- assumption: assumption,
547
- trace: trace,
548
- constraints: constraints
549
- end.yield_self do |results|
550
- results.find(&:success?) || results[0]
551
- end
530
+ super_method.method_types.map do |super_type|
531
+ sub_method.method_types.map do |sub_type|
532
+ check_generic_method_type name,
533
+ sub_type,
534
+ super_type,
535
+ self_type: self_type,
536
+ assumption: assumption,
537
+ trace: trace,
538
+ constraints: constraints
552
539
  end.yield_self do |results|
553
- if results.all?(&:success?) || sub_method.incompatible?
554
- success constraints: constraints
555
- else
556
- results.select(&:failure?).last
557
- end
540
+ results.find(&:success?) || results[0]
541
+ end
542
+ end.yield_self do |results|
543
+ if results.all?(&:success?)
544
+ success constraints: constraints
545
+ else
546
+ results.select(&:failure?).last
558
547
  end
559
- else
560
- raise "aaaaaaaaaaaaaa"
561
548
  end
562
549
  end
563
550
  end
@@ -104,6 +104,14 @@ module Steep
104
104
  def add(var, sub_type: nil, super_type: nil)
105
105
  subs, supers = dictionary[var]
106
106
 
107
+ if sub_type.is_a?(AST::Types::Logic::Base)
108
+ sub_type = AST::Builtin.bool_type
109
+ end
110
+
111
+ if super_type.is_a?(AST::Types::Logic::Base)
112
+ super_type = AST::Builtin.bool_type
113
+ end
114
+
107
115
  if super_type && !super_type.is_a?(AST::Types::Top)
108
116
  supers << eliminate_variable(super_type, to: AST::Types::Top.new)
109
117
  end
@@ -33,6 +33,8 @@ module Steep
33
33
  end
34
34
  end
35
35
 
36
+ include ModuleHelper
37
+
36
38
  attr_reader :checker
37
39
  attr_reader :source
38
40
  attr_reader :annotations
@@ -113,6 +115,7 @@ module Steep
113
115
  end
114
116
 
115
117
  def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
118
+ Steep.logger.debug { "check_relation: self:#{self_type} |- #{sub_type} <: #{super_type}" }
116
119
  checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
117
120
  end
118
121
 
@@ -168,7 +171,7 @@ module Steep
168
171
 
169
172
  super_method = if definition
170
173
  if (this_method = definition.methods[method_name])
171
- if module_context&.class_name == checker.factory.type_name(this_method.defined_in)
174
+ if module_context&.class_name == this_method.defined_in
172
175
  this_method.super_method
173
176
  else
174
177
  this_method
@@ -253,7 +256,7 @@ module Steep
253
256
  end
254
257
 
255
258
  if name
256
- absolute_name_ = checker.factory.type_name_1(name)
259
+ absolute_name_ = name
257
260
  entry = checker.factory.env.class_decls[absolute_name_]
258
261
  AST::Annotation::Implements::Module.new(
259
262
  name: name,
@@ -264,7 +267,7 @@ module Steep
264
267
  end
265
268
 
266
269
  def for_module(node)
267
- new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
270
+ new_module_name = module_name_from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
268
271
  new_namespace = nested_namespace_for_module(new_module_name)
269
272
 
270
273
  const_context = [new_namespace] + self.module_context.const_env.context
@@ -279,14 +282,13 @@ module Steep
279
282
  module_name = implement_module_name.name
280
283
  module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
281
284
 
282
- type_name_ = checker.factory.type_name_1(implement_module_name.name)
285
+ type_name_ = implement_module_name.name
283
286
  module_entry = checker.factory.definition_builder.env.class_decls[type_name_]
284
287
  instance_def = checker.factory.definition_builder.build_instance(type_name_)
285
288
  module_def = checker.factory.definition_builder.build_singleton(type_name_)
286
289
 
287
290
  instance_type = AST::Types::Intersection.build(
288
291
  types: [
289
- AST::Types::Name::Instance.new(name: module_name, args: module_args),
290
292
  AST::Builtin::Object.instance_type,
291
293
  *module_entry.self_types.map {|module_self|
292
294
  type = case
@@ -304,11 +306,12 @@ module Steep
304
306
  )
305
307
  end
306
308
  checker.factory.type(type)
307
- }
309
+ },
310
+ AST::Types::Name::Instance.new(name: module_name, args: module_args)
308
311
  ].compact
309
312
  )
310
313
 
311
- module_type = AST::Types::Name::Class.new(name: module_name, constructor: nil)
314
+ module_type = AST::Types::Name::Singleton.new(name: module_name)
312
315
  end
313
316
 
314
317
  if annots.instance_type
@@ -358,8 +361,8 @@ module Steep
358
361
  end
359
362
 
360
363
  def for_class(node)
361
- new_class_name = Names::Module.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
362
- super_class_name = node.children[1] && Names::Module.from_node(node.children[1])
364
+ new_class_name = module_name_from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
365
+ super_class_name = node.children[1] && module_name_from_node(node.children[1])
363
366
  new_namespace = nested_namespace_for_module(new_class_name)
364
367
 
365
368
  annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
@@ -374,12 +377,12 @@ module Steep
374
377
  class_name = implement_module_name.name
375
378
  class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
376
379
 
377
- type_name_ = checker.factory.type_name_1(implement_module_name.name)
380
+ type_name_ = implement_module_name.name
378
381
  instance_def = checker.factory.definition_builder.build_instance(type_name_)
379
382
  module_def = checker.factory.definition_builder.build_singleton(type_name_)
380
383
 
381
384
  instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
382
- module_type = AST::Types::Name::Class.new(name: class_name, constructor: nil)
385
+ module_type = AST::Types::Name::Singleton.new(name: class_name)
383
386
  end
384
387
 
385
388
  if annots.instance_type
@@ -443,28 +446,36 @@ module Steep
443
446
  end
444
447
 
445
448
  module_type = case instance_type
446
- when AST::Types::Name::Class
447
- AST::Builtin::Class.instance_type
448
- when AST::Types::Name::Module
449
- AST::Builtin::Module.instance_type
449
+ when AST::Types::Name::Singleton
450
+ type_name = instance_type.name
451
+
452
+ case checker.factory.env.class_decls[type_name]
453
+ when RBS::Environment::ModuleEntry
454
+ AST::Builtin::Module.instance_type
455
+ when RBS::Environment::ClassEntry
456
+ AST::Builtin::Class.instance_type
457
+ else
458
+ raise
459
+ end
460
+
450
461
  when AST::Types::Name::Instance
451
- instance_type.to_class(constructor: nil)
462
+ instance_type.to_module
452
463
  else
453
- raise "Unexpected type for sclass node: #{type}"
464
+ return
454
465
  end
455
466
 
456
467
  instance_definition = case instance_type
457
- when AST::Types::Name::Class, AST::Types::Name::Module
458
- type_name = checker.factory.type_name_1(instance_type.name)
468
+ when AST::Types::Name::Singleton
469
+ type_name = instance_type.name
459
470
  checker.factory.definition_builder.build_singleton(type_name)
460
471
  when AST::Types::Name::Instance
461
- type_name = checker.factory.type_name_1(instance_type.name)
472
+ type_name = instance_type.name
462
473
  checker.factory.definition_builder.build_instance(type_name)
463
474
  end
464
475
 
465
476
  module_definition = case module_type
466
- when AST::Types::Name::Class, AST::Types::Name::Module
467
- type_name = checker.factory.type_name_1(instance_type.name)
477
+ when AST::Types::Name::Singleton
478
+ type_name = instance_type.name
468
479
  checker.factory.definition_builder.build_singleton(type_name)
469
480
  else
470
481
  nil
@@ -638,7 +649,10 @@ module Steep
638
649
  when :__skip__
639
650
  add_typing(node, type: AST::Builtin.any_type)
640
651
  else
641
- hint ||= context.lvar_env.declared_types[name]&.type
652
+ if !hint || hint.is_a?(AST::Types::Void)
653
+ hint = context.lvar_env.declared_types[name]&.type
654
+ end
655
+
642
656
  rhs_result = synthesize(rhs, hint: hint)
643
657
 
644
658
  constr = rhs_result.constr.update_lvar_env do |lvar_env|
@@ -683,8 +697,8 @@ module Steep
683
697
  yield_self do
684
698
  if self_class?(node)
685
699
  module_type = expand_alias(module_context.module_type)
686
- type = if module_type.is_a?(AST::Types::Name::Class)
687
- AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
700
+ type = if module_type.is_a?(AST::Types::Name::Singleton)
701
+ AST::Types::Name::Singleton.new(name: module_type.name)
688
702
  else
689
703
  module_type
690
704
  end
@@ -699,8 +713,8 @@ module Steep
699
713
  yield_self do
700
714
  pair = if self_class?(node)
701
715
  module_type = expand_alias(module_context.module_type)
702
- type = if module_type.is_a?(AST::Types::Name::Class)
703
- AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
716
+ type = if module_type.is_a?(AST::Types::Name::Singleton)
717
+ AST::Types::Name::Singleton.new(name: module_type.name)
704
718
  else
705
719
  module_type
706
720
  end
@@ -744,6 +758,23 @@ module Steep
744
758
 
745
759
  constr.add_typing(node, type: type)
746
760
 
761
+ when :cvasgn
762
+ var_node = lhs.updated(:cvar)
763
+ send_node = rhs.updated(:send, [var_node, op, rhs])
764
+ new_node = node.updated(:cvasgn, [lhs.children[0], send_node])
765
+
766
+ type, constr = synthesize(new_node, hint: hint)
767
+
768
+ constr.add_typing(node, type: type)
769
+
770
+ when :send
771
+ new_rhs = rhs.updated(:send, [lhs, node.children[1], node.children[2]])
772
+ new_node = lhs.updated(:send, [lhs.children[0], :"#{lhs.children[1]}=", *lhs.children.drop(2), new_rhs])
773
+
774
+ type, constr = synthesize(new_node, hint: hint)
775
+
776
+ constr.add_typing(node, type: type)
777
+
747
778
  else
748
779
  Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
749
780
 
@@ -760,11 +791,10 @@ module Steep
760
791
  synthesize(child)
761
792
  end
762
793
 
763
- super_method = Interface::Interface::Combination.overload(
764
- method_context.super_method.method_types.map {|method_type|
794
+ super_method = Interface::Interface::Entry.new(
795
+ method_types: method_context.super_method.method_types.map {|method_type|
765
796
  checker.factory.method_type(method_type, self_type: self_type)
766
- },
767
- incompatible: false
797
+ }
768
798
  )
769
799
  args = TypeInference::SendArgs.from_nodes(node.children.dup)
770
800
 
@@ -811,7 +841,7 @@ module Steep
811
841
  new.typing.add_context_for_body(node, context: new.context)
812
842
 
813
843
  each_child_node(args_node) do |arg|
814
- new.synthesize(arg)
844
+ _, new = new.synthesize(arg)
815
845
  end
816
846
 
817
847
  body_pair = if body_node
@@ -860,10 +890,10 @@ module Steep
860
890
  self_type = expand_self(self_type)
861
891
  definition = case self_type
862
892
  when AST::Types::Name::Instance
863
- name = checker.factory.type_name_1(self_type.name)
893
+ name = self_type.name
864
894
  checker.factory.definition_builder.build_singleton(name)
865
- when AST::Types::Name::Module, AST::Types::Name::Class
866
- name = checker.factory.type_name_1(self_type.name)
895
+ when AST::Types::Name::Singleton
896
+ name = self_type.name
867
897
  checker.factory.definition_builder.build_singleton(name)
868
898
  end
869
899
 
@@ -999,11 +1029,17 @@ module Steep
999
1029
  yield_self do
1000
1030
  var = node.children[0]
1001
1031
  type = context.lvar_env[var.name]
1002
- unless type
1032
+
1033
+ if type
1034
+ add_typing(node, type: type)
1035
+ else
1003
1036
  type = AST::Builtin.any_type
1004
- Steep.logger.error { "Unknown arg type: #{node}" }
1037
+ if context&.method_context&.method_type
1038
+ Steep.logger.error { "Unknown arg type: #{node}" }
1039
+ end
1040
+
1041
+ lvasgn(node, type)
1005
1042
  end
1006
- add_typing(node, type: type)
1007
1043
  end
1008
1044
 
1009
1045
  when :optarg, :kwoptarg
@@ -1011,12 +1047,13 @@ module Steep
1011
1047
  var = node.children[0]
1012
1048
  rhs = node.children[1]
1013
1049
 
1014
- type = context.lvar_env[var.name]
1050
+ var_type = context.lvar_env[var.name]
1051
+ node_type, constr = synthesize(rhs, hint: var_type)
1015
1052
 
1016
- node_type, constr = synthesize(rhs, hint: type)
1053
+ type = AST::Types::Union.build(types: [var_type, node_type])
1017
1054
 
1018
1055
  constr_ = constr.update_lvar_env do |env|
1019
- env.assign(var.name, node: node, type: node_type) do |declared_type, type, result|
1056
+ env.assign(var.name, node: node, type: type) do |declared_type, type, result|
1020
1057
  typing.add_error(
1021
1058
  Errors::IncompatibleAssignment.new(node: node,
1022
1059
  lhs_type: declared_type,
@@ -1026,7 +1063,7 @@ module Steep
1026
1063
  end
1027
1064
  end
1028
1065
 
1029
- add_typing(node, type: constr_.context.lvar_env[var.name], constr: constr_)
1066
+ add_typing(node, type: type, constr: constr_)
1030
1067
  end
1031
1068
 
1032
1069
  when :restarg
@@ -1034,7 +1071,9 @@ module Steep
1034
1071
  var = node.children[0]
1035
1072
  type = context.lvar_env[var.name]
1036
1073
  unless type
1037
- Steep.logger.error { "Unknown variable: #{node}" }
1074
+ if context&.method_context&.method_type
1075
+ Steep.logger.error { "Unknown variable: #{node}" }
1076
+ end
1038
1077
  typing.add_error Errors::FallbackAny.new(node: node)
1039
1078
  type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
1040
1079
  end
@@ -1047,7 +1086,9 @@ module Steep
1047
1086
  var = node.children[0]
1048
1087
  type = context.lvar_env[var.name]
1049
1088
  unless type
1050
- Steep.logger.error { "Unknown variable: #{node}" }
1089
+ if context&.method_context&.method_type
1090
+ Steep.logger.error { "Unknown variable: #{node}" }
1091
+ end
1051
1092
  typing.add_error Errors::FallbackAny.new(node: node)
1052
1093
  type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
1053
1094
  end
@@ -1202,6 +1243,17 @@ module Steep
1202
1243
  type, constr = synthesize(node.children[0])
1203
1244
  constructor = constr.for_sclass(node, type)
1204
1245
 
1246
+ unless constructor
1247
+ typing.add_error(
1248
+ Errors::UnsupportedSyntax.new(
1249
+ node: node,
1250
+ message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
1251
+ )
1252
+ )
1253
+ constr.add_typing(node, type: AST::Builtin.nil_type)
1254
+ return
1255
+ end
1256
+
1205
1257
  constructor.typing.add_context_for_node(node, context: constructor.context)
1206
1258
  constructor.typing.add_context_for_body(node, context: constructor.context)
1207
1259
 
@@ -1213,14 +1265,14 @@ module Steep
1213
1265
  end
1214
1266
  end
1215
1267
 
1216
- add_typing(node, type: AST::Builtin.nil_type)
1268
+ constr.add_typing(node, type: AST::Builtin.nil_type)
1217
1269
  end
1218
1270
 
1219
1271
  when :self
1220
1272
  add_typing node, type: AST::Types::Self.new
1221
1273
 
1222
1274
  when :const
1223
- const_name = Names::Module.from_node(node)
1275
+ const_name = module_name_from_node(node)
1224
1276
 
1225
1277
  if const_name
1226
1278
  type = type_env.get(const: const_name) do
@@ -1233,7 +1285,7 @@ module Steep
1233
1285
 
1234
1286
  when :casgn
1235
1287
  yield_self do
1236
- const_name = Names::Module.from_node(node)
1288
+ const_name = module_name_from_node(node)
1237
1289
  if const_name
1238
1290
  const_type = type_env.get(const: const_name) {}
1239
1291
  value_type = synthesize(node.children.last, hint: const_type).type
@@ -1301,84 +1353,62 @@ module Steep
1301
1353
  when :array
1302
1354
  yield_self do
1303
1355
  if node.children.empty?
1304
- typing.add_error Errors::FallbackAny.new(node: node) unless hint
1305
-
1306
- array_type = if hint
1307
- if check_relation(sub_type: AST::Builtin::Array.instance_type(AST::Builtin.any_type),
1308
- super_type: hint).success?
1309
- hint
1310
- end
1311
- end
1312
-
1313
- add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
1314
- else
1315
- is_tuple = nil
1316
-
1317
- expand_alias(hint) do |hint|
1318
- is_tuple = hint.is_a?(AST::Types::Tuple)
1319
- is_tuple &&= node.children.all? {|child| child.type != :splat}
1320
- is_tuple &&= node.children.size >= hint.types.size
1321
- is_tuple &&= hint.types.map.with_index do |child_type, index|
1322
- child_node = node.children[index]
1323
- [synthesize(child_node, hint: child_type).type, child_type]
1324
- end.all? do |node_type, hint_type|
1325
- result = check_relation(sub_type: node_type, super_type: hint_type)
1326
- result.success?
1356
+ if hint
1357
+ array = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
1358
+ if check_relation(sub_type: array, super_type: hint).success?
1359
+ add_typing node, type: hint
1360
+ else
1361
+ add_typing node, type: array
1327
1362
  end
1328
- end
1329
-
1330
- if is_tuple
1331
- array_type = hint
1332
1363
  else
1333
- element_hint = expand_alias(hint) do |hint|
1334
- AST::Builtin::Array.instance_type?(hint) && hint.args[0]
1364
+ typing.add_error Errors::FallbackAny.new(node: node)
1365
+ add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
1366
+ end
1367
+ else
1368
+ node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
1369
+
1370
+ if hint && !(tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) }).empty?
1371
+ tuples.each do |tuple|
1372
+ typing.new_child(node_range) do |child_typing|
1373
+ pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
1374
+ if pair && pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
1375
+ child_typing.save!
1376
+ return pair.with(constr: pair.constr.with_new_typing(typing))
1377
+ end
1378
+ end
1335
1379
  end
1380
+ end
1336
1381
 
1337
- element_types = node.children.flat_map do |e|
1338
- if e.type == :splat
1339
- Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
1340
- synthesize(e.children.first).type.yield_self do |type|
1341
- expand_alias(type) do |ty|
1342
- case ty
1343
- when AST::Types::Union
1344
- ty.types
1345
- else
1346
- [ty]
1347
- end
1348
- end
1349
- end.map do |type|
1350
- case
1351
- when AST::Builtin::Array.instance_type?(type)
1352
- type.args.first
1353
- when AST::Builtin::Range.instance_type?(type)
1354
- type.args.first
1355
- else
1356
- type
1357
- end
1382
+ if hint && !(arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) }).empty?
1383
+ arrays.each do |array|
1384
+ typing.new_child(node_range) do |child_typing|
1385
+ pair = with_new_typing(child_typing).try_array_type(node, array)
1386
+ if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
1387
+ child_typing.save!
1388
+ return pair.with(constr: pair.constr.with_new_typing(typing))
1358
1389
  end
1359
- else
1360
- [select_super_type(synthesize(e, hint: element_hint).type, element_hint)]
1361
1390
  end
1362
1391
  end
1363
- array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
1364
1392
  end
1365
1393
 
1366
- add_typing(node, type: array_type)
1394
+ try_array_type(node, nil)
1367
1395
  end
1368
1396
  end
1369
1397
 
1370
1398
  when :and
1371
1399
  yield_self do
1372
1400
  left, right = node.children
1373
- logic = TypeInference::Logic.new(subtyping: checker)
1374
- truthy, falsey = logic.nodes(node: left)
1375
1401
 
1376
1402
  left_type, constr = synthesize(left)
1377
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1378
- falsey_vars: falsey.vars,
1379
- lvar_env: constr.context.lvar_env)
1380
1403
 
1381
- right_type, constr = constr.update_lvar_env { truthy_env }.for_branch(right).synthesize(right)
1404
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1405
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
1406
+
1407
+ right_type, constr = constr
1408
+ .update_lvar_env { truthy_env }
1409
+ .tap {|constr| typing.add_context_for_node(right, context: constr.context) }
1410
+ .for_branch(right)
1411
+ .synthesize(right)
1382
1412
 
1383
1413
  type = if left_type.is_a?(AST::Types::Boolean)
1384
1414
  union_type(left_type, right_type)
@@ -1400,16 +1430,18 @@ module Steep
1400
1430
  when :or
1401
1431
  yield_self do
1402
1432
  left, right = node.children
1403
- logic = TypeInference::Logic.new(subtyping: checker)
1404
- truthy, falsey = logic.nodes(node: left)
1405
1433
 
1406
1434
  left_type, constr = synthesize(left, hint: hint)
1407
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1408
- falsey_vars: falsey.vars,
1409
- lvar_env: constr.context.lvar_env)
1410
- left_type_t, _ = logic.partition_union(left_type)
1411
1435
 
1412
- right_type, constr = constr.update_lvar_env { falsey_env }.for_branch(right).synthesize(right, hint: left_type_t)
1436
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1437
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
1438
+
1439
+ left_type_t, _ = checker.factory.unwrap_optional(left_type)
1440
+ right_type, constr = constr
1441
+ .update_lvar_env { falsey_env }
1442
+ .tap {|constr| typing.add_context_for_node(right, context: constr.context) }
1443
+ .for_branch(right)
1444
+ .synthesize(right, hint: left_type_t)
1413
1445
 
1414
1446
  type = union_type(left_type_t, right_type)
1415
1447
 
@@ -1428,12 +1460,8 @@ module Steep
1428
1460
  cond, true_clause, false_clause = node.children
1429
1461
 
1430
1462
  cond_type, constr = synthesize(cond)
1431
- logic = TypeInference::Logic.new(subtyping: checker)
1432
-
1433
- truthys, falseys = logic.nodes(node: cond)
1434
- truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
1435
- falsey_vars: falseys.vars,
1436
- lvar_env: constr.context.lvar_env)
1463
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
1464
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: cond_type, node: cond)
1437
1465
 
1438
1466
  if true_clause
1439
1467
  true_pair = constr
@@ -1483,90 +1511,109 @@ module Steep
1483
1511
  cond, *whens, els = node.children
1484
1512
 
1485
1513
  constr = self
1514
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1486
1515
 
1487
1516
  if cond
1488
- cond_type, constr = synthesize(cond)
1489
- cond_type = expand_alias(cond_type)
1490
- if cond_type.is_a?(AST::Types::Union)
1491
- var_names = TypeConstruction.value_variables(cond)
1492
- var_types = cond_type.types.dup
1493
- end
1494
- end
1517
+ branch_pairs = []
1495
1518
 
1496
- branch_pairs = []
1519
+ cond_type, constr = constr.synthesize(cond)
1520
+ _, cond_vars = interpreter.decompose_value(cond)
1497
1521
 
1498
- whens.each do |clause|
1499
- *tests, body = clause.children
1522
+ when_constr = constr
1523
+ whens.each do |clause|
1524
+ *tests, body = clause.children
1500
1525
 
1501
- test_types = []
1502
- clause_constr = constr
1526
+ test_constr = when_constr
1527
+ test_envs = []
1503
1528
 
1504
- tests.each do |test|
1505
- type, clause_constr = synthesize(test)
1506
- test_types << expand_alias(type)
1529
+ tests.each do |test|
1530
+ test_node = test.updated(:send, [test, :===, cond.dup])
1531
+ test_type, test_constr = test_constr.synthesize(test_node)
1532
+ truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
1533
+ test_envs << truthy_env
1534
+ test_constr = test_constr.update_lvar_env { falsy_env }
1535
+ end
1536
+
1537
+ body_constr = when_constr.update_lvar_env {|env| env.except(cond_vars).join(*test_envs) }
1538
+
1539
+ if body
1540
+ branch_pairs << body_constr
1541
+ .for_branch(body)
1542
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1543
+ .synthesize(body, hint: hint)
1544
+ else
1545
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
1546
+ end
1547
+
1548
+ when_constr = test_constr
1507
1549
  end
1508
1550
 
1509
- if body
1510
- if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Class) }
1511
- var_types_in_body = test_types.flat_map do |test_type|
1512
- filtered_types = var_types.select do |var_type|
1513
- var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
1514
- end
1515
- if filtered_types.empty?
1516
- to_instance_type(test_type)
1517
- else
1518
- filtered_types
1519
- end
1520
- end
1551
+ if els
1552
+ begin_pos = node.loc.else.end_pos
1553
+ end_pos = node.loc.end.begin_pos
1554
+ typing.add_context(begin_pos..end_pos, context: when_constr.context)
1521
1555
 
1522
- var_types.reject! do |type|
1523
- var_types_in_body.any? do |test_type|
1524
- type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1525
- end
1526
- end
1556
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1557
+ end
1527
1558
 
1528
- var_type_in_body = union_type(*var_types_in_body)
1529
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1530
- hash[var_name] = var_type_in_body
1531
- end
1559
+ types = branch_pairs.map(&:type)
1560
+ constrs = branch_pairs.map(&:constr)
1532
1561
 
1533
- branch_pairs << clause_constr
1534
- .for_branch(body, type_case_override: type_case_override)
1535
- .synthesize(body, hint: hint)
1536
- else
1537
- branch_pairs << clause_constr.synthesize(body, hint: hint)
1562
+ unless els
1563
+ constrs << when_constr
1564
+ end
1565
+
1566
+ if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
1567
+ # Exhaustive
1568
+ if els
1569
+ typing.add_error Errors::ElseOnExhaustiveCase.new(node: els, type: cond_type)
1538
1570
  end
1539
1571
  else
1540
- branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1572
+ unless els
1573
+ types << AST::Builtin.nil_type
1574
+ end
1541
1575
  end
1542
- end
1576
+ else
1577
+ branch_pairs = []
1578
+
1579
+ when_constr = constr
1543
1580
 
1544
- if els
1545
- if var_names && var_types
1546
- if var_types.empty?
1547
- typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1581
+ whens.each do |clause|
1582
+ *tests, body = clause.children
1583
+
1584
+ test_constr = when_constr
1585
+ test_envs = []
1586
+
1587
+ tests.each do |test|
1588
+ test_type, test_constr = test_constr.synthesize(test)
1589
+ truthy_env, falsy_env = interpreter.eval(env: test_constr.context.lvar_env, type: test_type, node: test)
1590
+ test_envs << truthy_env
1591
+ test_constr = test_constr.update_lvar_env { falsy_env }
1548
1592
  end
1549
1593
 
1550
- else_override = var_names.each.with_object({}) do |var_name, hash|
1551
- hash[var_name] = unless var_types.empty?
1552
- union_type(*var_types)
1553
- else
1554
- AST::Builtin.any_type
1555
- end
1594
+ clause_constr = when_constr.update_lvar_env {|env| env.join(*test_envs) }
1595
+ when_constr = test_constr
1596
+
1597
+ if body
1598
+ branch_pairs << clause_constr
1599
+ .for_branch(body)
1600
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1601
+ .synthesize(body, hint: hint)
1602
+ else
1603
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1556
1604
  end
1557
- branch_pairs << constr
1558
- .for_branch(els, type_case_override: else_override)
1559
- .synthesize(els, hint: hint)
1560
- else
1561
- branch_pairs << constr.synthesize(els, hint: hint)
1562
1605
  end
1563
- end
1564
1606
 
1565
- types = branch_pairs.map(&:type)
1566
- constrs = branch_pairs.map(&:constr)
1607
+ if els
1608
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1609
+ end
1610
+
1611
+ types = branch_pairs.map(&:type)
1612
+ constrs = branch_pairs.map(&:constr)
1567
1613
 
1568
- unless var_types&.empty? || els
1569
- types.push AST::Builtin.nil_type
1614
+ unless els
1615
+ types << AST::Builtin.nil_type
1616
+ end
1570
1617
  end
1571
1618
 
1572
1619
  constr = constr.update_lvar_env do |env|
@@ -1579,7 +1626,7 @@ module Steep
1579
1626
  when :rescue
1580
1627
  yield_self do
1581
1628
  body, *resbodies, else_node = node.children
1582
- body_pair = synthesize(body) if body
1629
+ body_pair = synthesize(body, hint: hint) if body
1583
1630
 
1584
1631
  body_constr = if body_pair
1585
1632
  self.update_lvar_env do |env|
@@ -1617,7 +1664,7 @@ module Steep
1617
1664
  instance_types = exn_types.map do |type|
1618
1665
  type = expand_alias(type)
1619
1666
  case
1620
- when type.is_a?(AST::Types::Name::Class)
1667
+ when type.is_a?(AST::Types::Name::Singleton)
1621
1668
  to_instance_type(type)
1622
1669
  else
1623
1670
  AST::Builtin.any_type
@@ -1631,7 +1678,7 @@ module Steep
1631
1678
  resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
1632
1679
 
1633
1680
  if body
1634
- resbody_construction.synthesize(body)
1681
+ resbody_construction.synthesize(body, hint: hint)
1635
1682
  else
1636
1683
  Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
1637
1684
  end
@@ -1641,7 +1688,7 @@ module Steep
1641
1688
  resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
1642
1689
 
1643
1690
  if else_node
1644
- else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
1691
+ else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node, hint: hint)
1645
1692
  add_typing(node,
1646
1693
  type: union_type(*[else_pair.type, *resbody_types].compact),
1647
1694
  constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
@@ -1657,7 +1704,7 @@ module Steep
1657
1704
  klasses, asgn, body = node.children
1658
1705
  synthesize(klasses) if klasses
1659
1706
  synthesize(asgn) if asgn
1660
- body_type = synthesize(body).type if body
1707
+ body_type = synthesize(body, hint: hint).type if body
1661
1708
  add_typing(node, type: body_type)
1662
1709
  end
1663
1710
 
@@ -1672,19 +1719,62 @@ module Steep
1672
1719
  when :masgn
1673
1720
  type_masgn(node)
1674
1721
 
1722
+ when :for
1723
+ yield_self do
1724
+ asgn, collection, body = node.children
1725
+
1726
+ collection_type, constr = synthesize(collection)
1727
+ collection_type = expand_self(collection_type)
1728
+
1729
+ var_type = case collection_type
1730
+ when AST::Types::Any
1731
+ AST::Types::Any.new
1732
+ else
1733
+ each = checker.factory.interface(collection_type, private: true).methods[:each]
1734
+ method_type = (each&.method_types || []).find {|type| type.block && type.block.type.params.first_param }
1735
+ method_type&.yield_self do |method_type|
1736
+ method_type.block.type.params.first_param&.type
1737
+ end
1738
+ end
1739
+
1740
+ if var_type
1741
+ if body
1742
+ body_constr = constr.with_updated_context(
1743
+ lvar_env: constr.context.lvar_env.assign(asgn.children[0].name, node: asgn, type: var_type)
1744
+ )
1745
+
1746
+ typing.add_context_for_body(node, context: body_constr.context)
1747
+ _, _, body_context = body_constr.synthesize(body)
1748
+
1749
+ constr = constr.update_lvar_env {|env| env.join(constr.context.lvar_env, body_context.lvar_env) }
1750
+ else
1751
+ constr = self
1752
+ end
1753
+
1754
+ add_typing(node, type: collection_type, constr: constr)
1755
+ else
1756
+ fallback_to_any(node) do
1757
+ Errors::NoMethod.new(
1758
+ node: node,
1759
+ method: :each,
1760
+ type: collection_type
1761
+ )
1762
+ end
1763
+ end
1764
+ end
1675
1765
  when :while, :until
1676
1766
  yield_self do
1677
1767
  cond, body = node.children
1678
- _, constr = synthesize(cond)
1768
+ cond_type, constr = synthesize(cond)
1679
1769
 
1680
- logic = TypeInference::Logic.new(subtyping: checker)
1681
- truthy, falsey = logic.nodes(node: cond)
1770
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1771
+ truthy_env, falsy_env = interpreter.eval(env: constr.context.lvar_env, node: cond, type: cond_type)
1682
1772
 
1683
1773
  case node.type
1684
1774
  when :while
1685
- body_env, exit_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1775
+ body_env, exit_env = truthy_env, falsy_env
1686
1776
  when :until
1687
- exit_env, body_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1777
+ exit_env, body_env = truthy_env, falsy_env
1688
1778
  end
1689
1779
 
1690
1780
  if body
@@ -1733,9 +1823,22 @@ module Steep
1733
1823
  end
1734
1824
 
1735
1825
  when :irange, :erange
1736
- types = node.children.map {|n| synthesize(n).type }
1737
- type = AST::Builtin::Range.instance_type(union_type(*types))
1738
- add_typing(node, type: type)
1826
+ begin_node, end_node = node.children
1827
+
1828
+ constr = self
1829
+ begin_type, constr = if begin_node
1830
+ constr.synthesize(begin_node)
1831
+ else
1832
+ [AST::Builtin.nil_type, constr]
1833
+ end
1834
+ end_type, constr = if end_node
1835
+ constr.synthesize(end_node)
1836
+ else
1837
+ [AST::Builtin.nil_type, constr]
1838
+ end
1839
+
1840
+ type = AST::Builtin::Range.instance_type(union_type(begin_type, end_type))
1841
+ add_typing(node, type: type, constr: constr)
1739
1842
 
1740
1843
  when :regexp
1741
1844
  each_child_node(node) do |child|
@@ -1753,9 +1856,36 @@ module Steep
1753
1856
 
1754
1857
  when :or_asgn, :and_asgn
1755
1858
  yield_self do
1756
- _, rhs = node.children
1757
- rhs_type = synthesize(rhs).type
1758
- add_typing(node, type: rhs_type)
1859
+ asgn, rhs = node.children
1860
+
1861
+ case asgn.type
1862
+ when :lvasgn
1863
+ type, constr = synthesize(rhs, hint: hint)
1864
+ constr.lvasgn(asgn, type)
1865
+ when :ivasgn
1866
+ type, constr = synthesize(rhs, hint: hint)
1867
+ constr.ivasgn(asgn, type)
1868
+ when :send
1869
+ rhs_ = node.updated(:send,
1870
+ [
1871
+ asgn.children[0],
1872
+ :"#{asgn.children[1]}=",
1873
+ asgn.children[2],
1874
+ rhs
1875
+ ])
1876
+ node_type = case node.type
1877
+ when :or_asgn
1878
+ :or
1879
+ when :and_asgn
1880
+ :and
1881
+ end
1882
+ node_ = node.updated(node_type, [asgn, rhs_])
1883
+
1884
+ synthesize(node_, hint: hint)
1885
+ else
1886
+ Steep.logger.error { "#{node.type} with #{asgn.type} lhs is not supported"}
1887
+ fallback_to_any(node)
1888
+ end
1759
1889
  end
1760
1890
 
1761
1891
  when :defined?
@@ -1802,8 +1932,8 @@ module Steep
1802
1932
  param_type = hint.params.required[0]
1803
1933
  interface = checker.factory.interface(param_type, private: true)
1804
1934
  method = interface.methods[value.children[0]]
1805
- if method&.overload?
1806
- return_types = method.types.select {|method_type|
1935
+ if method
1936
+ return_types = method.method_types.select {|method_type|
1807
1937
  method_type.params.each_type.count == 0
1808
1938
  }.map(&:return_type)
1809
1939
 
@@ -1831,9 +1961,50 @@ module Steep
1831
1961
  add_typing node, type: AST::Builtin.any_type
1832
1962
  end
1833
1963
 
1834
- when :splat, :sclass, :alias
1964
+ when :cvasgn
1965
+ name, rhs = node.children
1966
+
1967
+ type, constr = synthesize(rhs, hint: hint)
1968
+
1969
+ var_type = if module_context&.class_variables
1970
+ module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
1971
+ end
1972
+
1973
+ if var_type
1974
+ result = constr.check_relation(sub_type: type, super_type: var_type)
1975
+
1976
+ if result.success?
1977
+ add_typing node, type: type, constr: constr
1978
+ else
1979
+ fallback_to_any node do
1980
+ Errors::IncompatibleAssignment.new(node: node,
1981
+ lhs_type: var_type,
1982
+ rhs_type: type,
1983
+ result: result)
1984
+ end
1985
+ end
1986
+ else
1987
+ fallback_to_any(node)
1988
+ end
1989
+
1990
+ when :cvar
1991
+ name = node.children[0]
1992
+ var_type = if module_context&.class_variables
1993
+ module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
1994
+ end
1995
+
1996
+ if var_type
1997
+ add_typing node, type: var_type
1998
+ else
1999
+ fallback_to_any node
2000
+ end
2001
+
2002
+ when :alias
2003
+ add_typing node, type: AST::Builtin.nil_type
2004
+
2005
+ when :splat
1835
2006
  yield_self do
1836
- Steep.logger.error "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})"
2007
+ Steep.logger.warn { "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})" }
1837
2008
 
1838
2009
  each_child_node node do |child|
1839
2010
  synthesize(child)
@@ -1842,8 +2013,18 @@ module Steep
1842
2013
  add_typing node, type: AST::Builtin.any_type
1843
2014
  end
1844
2015
 
2016
+ when :args
2017
+ constr = self
2018
+
2019
+ each_child_node(node) do |child|
2020
+ _, constr = constr.synthesize(child)
2021
+ end
2022
+
2023
+ add_typing node, type: AST::Builtin.any_type, constr: constr
2024
+
1845
2025
  else
1846
2026
  raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
2027
+
1847
2028
  end.tap do |pair|
1848
2029
  unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
1849
2030
  # Steep.logger.error { "result = #{pair.inspect}" }
@@ -1883,136 +2064,202 @@ module Steep
1883
2064
  add_typing(node, type: ivar_type)
1884
2065
  end
1885
2066
 
2067
+ def masgn_lhs?(lhs)
2068
+ lhs.children.all? do |a|
2069
+ asgn_type = if a.type == :splat
2070
+ a.children[0].type
2071
+ else
2072
+ a.type
2073
+ end
2074
+ asgn_type == :lvasgn || asgn_type == :ivasgn
2075
+ end
2076
+ end
2077
+
2078
+ def lvasgn(node, type)
2079
+ name = node.children[0].name
2080
+ env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
2081
+ typing.add_error(
2082
+ Errors::IncompatibleAssignment.new(node: node,
2083
+ lhs_type: declared_type,
2084
+ rhs_type: type,
2085
+ result: result)
2086
+ )
2087
+ end
2088
+
2089
+ add_typing(node, type: type, constr: with_updated_context(lvar_env: env))
2090
+ end
2091
+
2092
+ def ivasgn(node, type)
2093
+ ivar = node.children[0]
2094
+
2095
+ type_env.assign(ivar: ivar, type: type, self_type: self_type) do |error|
2096
+ case error
2097
+ when Subtyping::Result::Failure
2098
+ var_type = type_env.get(ivar: ivar)
2099
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
2100
+ lhs_type: var_type,
2101
+ rhs_type: type,
2102
+ result: error))
2103
+ when nil
2104
+ fallback_to_any node
2105
+ end
2106
+ end
2107
+
2108
+ add_typing(node, type: type)
2109
+ end
2110
+
1886
2111
  def type_masgn(node)
1887
2112
  lhs, rhs = node.children
1888
2113
  rhs_pair = synthesize(rhs)
1889
- rhs_type = expand_alias(rhs_pair.type)
2114
+ rhs_type = deep_expand_alias(rhs_pair.type)
1890
2115
 
1891
2116
  constr = rhs_pair.constr
1892
2117
 
1893
- if lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
1894
- case
1895
- when rhs.type == :array && lhs.children.size == rhs.children.size
1896
- # a, @b = x, y
2118
+ unless masgn_lhs?(lhs)
2119
+ Steep.logger.error("Unsupported masgn lhs node: only lvasgn, ivasgn, and splat are supported")
2120
+ _, constr = constr.fallback_to_any(lhs)
2121
+ return add_typing(node, type: rhs_type, constr: constr)
2122
+ end
1897
2123
 
1898
- constr = lhs.children.zip(rhs.children).inject(constr) do |ctr, (lhs, rhs)|
1899
- case lhs.type
1900
- when :lvasgn
1901
- name = lhs.children[0].name
1902
- type = typing.type_of(node: rhs)
1903
- env = ctr.context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
1904
- typing.add_error(
1905
- Errors::IncompatibleAssignment.new(node: lhs,
1906
- lhs_type: declared_type,
1907
- rhs_type: type,
1908
- result: result)
1909
- )
1910
- end
1911
- add_typing(lhs,
1912
- type: type,
1913
- constr: ctr.with_updated_context(lvar_env: env))
1914
- when :ivasgn
1915
- type_ivasgn(lhs.children.first, rhs, lhs)
1916
- constr
1917
- end
2124
+ falseys, truthys = partition_flatten_types(rhs_type) do |type|
2125
+ type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
2126
+ end
2127
+
2128
+ unwrap_rhs_type = AST::Types::Union.build(types: truthys)
2129
+
2130
+ case
2131
+ when unwrap_rhs_type.is_a?(AST::Types::Tuple) || (rhs.type == :array && rhs.children.none? {|n| n.type == :splat })
2132
+ tuple_types = if unwrap_rhs_type.is_a?(AST::Types::Tuple)
2133
+ unwrap_rhs_type.types.dup
2134
+ else
2135
+ rhs.children.map do |node|
2136
+ typing.type_of(node: node)
2137
+ end
2138
+ end
2139
+
2140
+ assignment_nodes = lhs.children.dup
2141
+ leading_assignments = []
2142
+ trailing_assignments = []
2143
+
2144
+ until assignment_nodes.empty?
2145
+ cursor = assignment_nodes.first
2146
+
2147
+ if cursor.type == :splat
2148
+ break
2149
+ else
2150
+ leading_assignments << assignment_nodes.shift
1918
2151
  end
2152
+ end
1919
2153
 
1920
- add_typing(node, type: rhs_type, constr: constr)
2154
+ until assignment_nodes.empty?
2155
+ cursor = assignment_nodes.last
1921
2156
 
1922
- when rhs_type.is_a?(AST::Types::Tuple)
1923
- # a, @b = tuple
2157
+ if cursor.type == :splat
2158
+ break
2159
+ else
2160
+ trailing_assignments.unshift assignment_nodes.pop
2161
+ end
2162
+ end
1924
2163
 
1925
- constr = lhs.children.zip(rhs_type.types).inject(constr) do |ctr, (lhs, type)|
1926
- ty = type || AST::Builtin.nil_type
2164
+ leading_assignments.each do |asgn|
2165
+ type = tuple_types.first
1927
2166
 
1928
- case lhs.type
1929
- when :lvasgn
1930
- name = lhs.children[0].name
1931
- env = ctr.context.lvar_env.assign(name, node: node, type: ty) do |declared_type, type, result|
1932
- typing.add_error(
1933
- Errors::IncompatibleAssignment.new(node: lhs,
1934
- lhs_type: declared_type,
1935
- rhs_type: type,
1936
- result: result)
1937
- )
1938
- end
1939
- add_typing(lhs,
1940
- type: ty,
1941
- constr: ctr.with_updated_context(lvar_env: env)).constr
1942
- when :ivasgn
1943
- ivar = lhs.children[0]
2167
+ if type
2168
+ tuple_types.shift
2169
+ else
2170
+ type = AST::Builtin.nil_type
2171
+ end
1944
2172
 
1945
- type_env.assign(ivar: ivar, type: ty, self_type: self_type) do |error|
1946
- case error
1947
- when Subtyping::Result::Failure
1948
- ivar_type = type_env.get(ivar: ivar)
1949
- typing.add_error(Errors::IncompatibleAssignment.new(node: lhs,
1950
- lhs_type: ivar_type,
1951
- rhs_type: ty,
1952
- result: error))
1953
- when nil
1954
- fallback_to_any node
1955
- end
1956
- end
2173
+ case asgn.type
2174
+ when :lvasgn
2175
+ _, constr = constr.lvasgn(asgn, type)
2176
+ when :ivasgn
2177
+ _, constr = constr.ivasgn(asgn, type)
2178
+ end
2179
+ end
1957
2180
 
1958
- ctr
1959
- end
2181
+ trailing_assignments.reverse_each do |asgn|
2182
+ type = tuple_types.last
2183
+
2184
+ if type
2185
+ tuple_types.pop
2186
+ else
2187
+ type = AST::Builtin.nil_type
1960
2188
  end
1961
2189
 
1962
- add_typing(node, type: rhs_type, constr: constr)
2190
+ case asgn.type
2191
+ when :lvasgn
2192
+ _, constr = constr.lvasgn(asgn, type)
2193
+ when :ivasgn
2194
+ _, constr = constr.ivasgn(asgn, type)
2195
+ end
2196
+ end
1963
2197
 
1964
- when AST::Builtin::Array.instance_type?(rhs_type)
1965
- element_type = AST::Types::Union.build(types: [rhs_type.args.first, AST::Builtin.nil_type])
2198
+ element_type = if tuple_types.empty?
2199
+ AST::Builtin.nil_type
2200
+ else
2201
+ AST::Types::Union.build(types: tuple_types)
2202
+ end
2203
+ array_type = AST::Builtin::Array.instance_type(element_type)
1966
2204
 
1967
- constr = lhs.children.inject(constr) do |ctr, assignment|
1968
- case assignment.type
2205
+ assignment_nodes.each do |asgn|
2206
+ case asgn.type
2207
+ when :splat
2208
+ case asgn.children[0].type
1969
2209
  when :lvasgn
1970
- name = assignment.children[0].name
1971
- env = ctr.context.lvar_env.assign(name, node: node, type: element_type) do |declared_type, type, result|
1972
- typing.add_error(
1973
- Errors::IncompatibleAssignment.new(node: assignment,
1974
- lhs_type: declared_type,
1975
- rhs_type: type,
1976
- result: result)
1977
- )
1978
- end
2210
+ _, constr = constr.lvasgn(asgn.children[0], array_type)
2211
+ when :ivasgn
2212
+ _, constr = constr.ivasgn(asgn.children[0], array_type)
2213
+ end
2214
+ when :lvasgn
2215
+ _, constr = constr.lvasgn(asgn, element_type)
2216
+ when :ivasgn
2217
+ _,constr = constr.ivasgn(asgn, element_type)
2218
+ end
2219
+ end
1979
2220
 
1980
- add_typing(assignment,
1981
- type: element_type,
1982
- constr: ctr.with_updated_context(lvar_env: env)).constr
2221
+ unless falseys.empty?
2222
+ constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
2223
+ end
1983
2224
 
1984
- when :ivasgn
1985
- ivar = assignment.children[0]
2225
+ add_typing(node, type: rhs_type, constr: constr)
1986
2226
 
1987
- type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
1988
- case error
1989
- when Subtyping::Result::Failure
1990
- type = type_env.get(ivar: ivar)
1991
- typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
1992
- lhs_type: type,
1993
- rhs_type: element_type,
1994
- result: error))
1995
- when nil
1996
- fallback_to_any node
1997
- end
1998
- end
2227
+ when flatten_union(unwrap_rhs_type).all? {|type| AST::Builtin::Array.instance_type?(type) }
2228
+ array_elements = flatten_union(unwrap_rhs_type).map {|type| type.args[0] }
2229
+ element_type = AST::Types::Union.build(types: array_elements + [AST::Builtin.nil_type])
2230
+
2231
+ constr = lhs.children.inject(constr) do |constr, assignment|
2232
+ case assignment.type
2233
+ when :lvasgn
2234
+ _, constr = constr.lvasgn(assignment, element_type)
1999
2235
 
2000
- ctr
2236
+ when :ivasgn
2237
+ _, constr = constr.ivasgn(assignment, element_type)
2238
+ when :splat
2239
+ case assignment.children[0].type
2240
+ when :lvasgn
2241
+ _, constr = constr.lvasgn(assignment.children[0], unwrap_rhs_type)
2242
+ when :ivasgn
2243
+ _, constr = constr.ivasgn(assignment.children[0], unwrap_rhs_type)
2244
+ else
2245
+ raise
2001
2246
  end
2002
2247
  end
2003
2248
 
2004
- add_typing node, type: rhs_type, constr: constr
2005
-
2006
- when rhs_type.is_a?(AST::Types::Any)
2007
- fallback_to_any(node)
2249
+ constr
2250
+ end
2008
2251
 
2009
- else
2010
- Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
2011
- fallback_to_any(node)
2252
+ unless falseys.empty?
2253
+ constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
2012
2254
  end
2255
+
2256
+ add_typing(node, type: rhs_type, constr: constr)
2013
2257
  else
2014
- Steep.logger.error("Unsupported masgn left hand side")
2015
- fallback_to_any(node)
2258
+ unless rhs_type.is_a?(AST::Types::Any)
2259
+ Steep.logger.error("Unsupported masgn rhs type: array or tuple is supported (#{rhs_type})")
2260
+ end
2261
+ _, constr = constr.fallback_to_any(lhs)
2262
+ add_typing(node, type: rhs_type, constr: constr)
2016
2263
  end
2017
2264
  end
2018
2265
 
@@ -2040,7 +2287,7 @@ module Steep
2040
2287
 
2041
2288
  def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2042
2289
  receiver, method_name, *arguments = send_node.children
2043
- receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
2290
+ receiver_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2044
2291
 
2045
2292
  if unwrap
2046
2293
  receiver_type = unwrap(receiver_type)
@@ -2048,74 +2295,80 @@ module Steep
2048
2295
 
2049
2296
  receiver_type = expand_alias(receiver_type)
2050
2297
 
2051
- pair = case receiver_type
2052
- when AST::Types::Any
2053
- add_typing node, type: AST::Builtin.any_type
2298
+ type, constr = case receiver_type
2299
+ when AST::Types::Any
2300
+ each_child_node(send_node) do |child|
2301
+ unless child.equal?(receiver)
2302
+ _, constr = constr.synthesize(child)
2303
+ end
2304
+ end
2054
2305
 
2055
- when nil
2056
- fallback_to_any node
2306
+ add_typing node, type: AST::Builtin.any_type
2057
2307
 
2058
- when AST::Types::Void, AST::Types::Bot, AST::Types::Top
2059
- fallback_to_any node do
2060
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2061
- end
2308
+ when nil
2309
+ fallback_to_any node
2062
2310
 
2063
- else
2064
- case expanded_receiver_type = expand_self(receiver_type)
2065
- when AST::Types::Self
2066
- Steep.logger.error "`self` type cannot be resolved to concrete type"
2067
- fallback_to_any node do
2068
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2069
- end
2070
- else
2071
- begin
2072
- interface = checker.factory.interface(receiver_type,
2073
- private: !receiver,
2074
- self_type: expanded_receiver_type)
2075
-
2076
- method = interface.methods[method_name]
2077
-
2078
- if method
2079
- args = TypeInference::SendArgs.from_nodes(arguments)
2080
- return_type, constr, _ = type_method_call(node,
2081
- method: method,
2082
- method_name: method_name,
2083
- args: args,
2084
- block_params: block_params,
2085
- block_body: block_body,
2086
- receiver_type: receiver_type,
2087
- topdown_hint: true)
2088
-
2089
- add_typing node, type: return_type, constr: constr
2090
- else
2091
- fallback_to_any node do
2092
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2093
- end
2094
- end
2095
- rescue => exn
2096
- case exn
2097
- when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2098
- # ignore known RBS errors.
2099
- else
2100
- Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2101
- end
2311
+ when AST::Types::Void, AST::Types::Bot, AST::Types::Top
2312
+ fallback_to_any node do
2313
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2314
+ end
2102
2315
 
2103
- fallback_to_any node do
2104
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2105
- end
2106
- end
2107
- end
2108
- end
2316
+ else
2317
+ case expanded_receiver_type = expand_self(receiver_type)
2318
+ when AST::Types::Self
2319
+ Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
2320
+ fallback_to_any node do
2321
+ Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2322
+ end
2323
+ else
2324
+ begin
2325
+ interface = checker.factory.interface(receiver_type,
2326
+ private: !receiver,
2327
+ self_type: expanded_receiver_type)
2328
+
2329
+ method = interface.methods[method_name]
2330
+
2331
+ if method
2332
+ args = TypeInference::SendArgs.from_nodes(arguments)
2333
+ return_type, constr, _ = constr.type_method_call(node,
2334
+ method: method,
2335
+ method_name: method_name,
2336
+ args: args,
2337
+ block_params: block_params,
2338
+ block_body: block_body,
2339
+ receiver_type: receiver_type,
2340
+ topdown_hint: true)
2341
+
2342
+ add_typing node, type: return_type, constr: constr
2343
+ else
2344
+ fallback_to_any node do
2345
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2346
+ end
2347
+ end
2348
+ rescue => exn
2349
+ case exn
2350
+ when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2351
+ # ignore known RBS errors.
2352
+ else
2353
+ Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2354
+ end
2355
+
2356
+ fallback_to_any node do
2357
+ Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2358
+ end
2359
+ end
2360
+ end
2361
+ end
2109
2362
 
2110
- case pair.type
2363
+ case type
2111
2364
  when nil, Errors::Base
2112
2365
  arguments.each do |arg|
2113
2366
  unless typing.has_type?(arg)
2114
2367
  if arg.type == :splat
2115
- type = synthesize(arg.children[0]).type
2368
+ type, constr = constr.synthesize(arg.children[0])
2116
2369
  add_typing(arg, type: AST::Builtin::Array.instance_type(type))
2117
2370
  else
2118
- synthesize(arg)
2371
+ _, constr = constr.synthesize(arg)
2119
2372
  end
2120
2373
  end
2121
2374
  end
@@ -2137,7 +2390,7 @@ module Steep
2137
2390
  end
2138
2391
  end
2139
2392
  else
2140
- pair
2393
+ Pair.new(type: type, constr: constr)
2141
2394
  end
2142
2395
  end
2143
2396
 
@@ -2204,139 +2457,68 @@ module Steep
2204
2457
  def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
2205
2458
  node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
2206
2459
 
2207
- case
2208
- when method.union?
2209
- yield_self do
2210
- results = method.types.map do |method|
2460
+ results = method.method_types.flat_map do |method_type|
2461
+ Steep.logger.tagged method_type.to_s do
2462
+ zips = args.zips(method_type.params, method_type.block&.type)
2463
+
2464
+ zips.map do |arg_pairs|
2211
2465
  typing.new_child(node_range) do |child_typing|
2212
- with_new_typing(child_typing).type_method_call(node,
2213
- method_name: method_name,
2214
- receiver_type: receiver_type,
2215
- method: method,
2216
- args: args,
2217
- block_params: block_params,
2218
- block_body: block_body,
2219
- topdown_hint: false)
2220
- end
2221
- end
2466
+ ret = self.with_new_typing(child_typing).try_method_type(
2467
+ node,
2468
+ receiver_type: receiver_type,
2469
+ method_type: method_type,
2470
+ args: args,
2471
+ arg_pairs: arg_pairs,
2472
+ block_params: block_params,
2473
+ block_body: block_body,
2474
+ child_typing: child_typing,
2475
+ topdown_hint: topdown_hint
2476
+ )
2222
2477
 
2223
- if (type, constr, error = results.find {|_, _, error| error })
2224
- constr.typing.save!
2225
- [type,
2226
- update_lvar_env { constr.context.lvar_env },
2227
- error]
2228
- else
2229
- types = results.map(&:first)
2478
+ raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2230
2479
 
2231
- _, constr, _ = results.first
2232
- constr.typing.save!
2480
+ result, constr = ret
2233
2481
 
2234
- [union_type(*types),
2235
- update_lvar_env { constr.context.lvar_env },
2236
- nil]
2482
+ [result, constr, method_type]
2483
+ end
2237
2484
  end
2238
2485
  end
2486
+ end
2239
2487
 
2240
- when method.intersection?
2241
- yield_self do
2242
- results = method.types.map do |method|
2243
- typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2244
- with_new_typing(child_typing).type_method_call(node,
2488
+ unless results.empty?
2489
+ result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2490
+ else
2491
+ method_type = method.method_types.last
2492
+ constr = self.with_new_typing(typing.new_child(node_range))
2493
+ result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
2494
+ end
2495
+ constr.typing.save!
2496
+
2497
+ case result
2498
+ when Errors::Base
2499
+ if method.method_types.size == 1
2500
+ typing.add_error result
2501
+ type = case method_type.return_type
2502
+ when AST::Types::Var
2503
+ AST::Builtin.any_type
2504
+ else
2505
+ method_type.return_type
2506
+ end
2507
+ else
2508
+ typing.add_error Errors::UnresolvedOverloading.new(node: node,
2509
+ receiver_type: expand_self(receiver_type),
2245
2510
  method_name: method_name,
2246
- receiver_type: receiver_type,
2247
- method: method,
2248
- args: args,
2249
- block_params: block_params,
2250
- block_body: block_body,
2251
- topdown_hint: false)
2252
- end
2253
- end
2254
-
2255
- successes = results.reject {|_, _, error| error }
2256
- unless successes.empty?
2257
- types = successes.map(&:first)
2258
- constr = successes[0][1]
2259
- constr.typing.save!
2260
-
2261
- [AST::Types::Intersection.build(types: types),
2262
- update_lvar_env { constr.context.lvar_env },
2263
- nil]
2264
- else
2265
- type, constr, error = results.first
2266
- constr.typing.save!
2267
-
2268
- [type,
2269
- update_lvar_env { constr.context.lvar_env },
2270
- error]
2271
- end
2511
+ method_types: method.method_types)
2512
+ type = AST::Builtin.any_type
2272
2513
  end
2273
2514
 
2274
- when method.overload?
2275
- yield_self do
2276
- results = method.types.flat_map do |method_type|
2277
- Steep.logger.tagged method_type.to_s do
2278
- zips = args.zips(method_type.params, method_type.block&.type)
2279
-
2280
- zips.map do |arg_pairs|
2281
- typing.new_child(node_range) do |child_typing|
2282
- ret = self.with_new_typing(child_typing).try_method_type(
2283
- node,
2284
- receiver_type: receiver_type,
2285
- method_type: method_type,
2286
- args: args,
2287
- arg_pairs: arg_pairs,
2288
- block_params: block_params,
2289
- block_body: block_body,
2290
- child_typing: child_typing,
2291
- topdown_hint: topdown_hint
2292
- )
2293
-
2294
- raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2295
-
2296
- result, constr = ret
2297
-
2298
- [result, constr, method_type]
2299
- end
2300
- end
2301
- end
2302
- end
2303
-
2304
- unless results.empty?
2305
- result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2306
- else
2307
- method_type = method.types.last
2308
- constr = self.with_new_typing(typing.new_child(node_range))
2309
- result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
2310
- end
2311
- constr.typing.save!
2312
-
2313
- case result
2314
- when Errors::Base
2315
- if method.types.size == 1
2316
- typing.add_error result
2317
- type = case method_type.return_type
2318
- when AST::Types::Var
2319
- AST::Builtin.any_type
2320
- else
2321
- method_type.return_type
2322
- end
2323
- else
2324
- typing.add_error Errors::UnresolvedOverloading.new(node: node,
2325
- receiver_type: expand_self(receiver_type),
2326
- method_name: method_name,
2327
- method_types: method.types)
2328
- type = AST::Builtin.any_type
2329
- end
2330
-
2331
- [type,
2332
- update_lvar_env { constr.context.lvar_env },
2333
- result]
2334
- else # Type
2335
- [result,
2336
- update_lvar_env { constr.context.lvar_env },
2337
- nil]
2338
- end
2339
- end
2515
+ [type,
2516
+ update_lvar_env { constr.context.lvar_env },
2517
+ result]
2518
+ else # Type
2519
+ [result,
2520
+ update_lvar_env { constr.context.lvar_env },
2521
+ nil]
2340
2522
  end
2341
2523
  end
2342
2524
 
@@ -2523,16 +2705,40 @@ module Steep
2523
2705
  if block_params && method_type.block
2524
2706
  block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2525
2707
  block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2526
- block_param_hint = block_params_.params_type(
2527
- hint: topdown_hint ? method_type.block.type.params : nil
2528
- )
2529
2708
 
2530
- check_relation(sub_type: AST::Types::Proc.new(params: block_param_hint, return_type: AST::Types::Any.new),
2531
- super_type: method_type.block.type,
2532
- constraints: constraints).else do |result|
2533
- return [Errors::IncompatibleBlockParameters.new(node: node,
2534
- method_type: method_type),
2535
- constr]
2709
+ unless block_params_
2710
+ return [
2711
+ Errors::UnsupportedSyntax.new(
2712
+ node: block_params,
2713
+ message: "Unsupported block params pattern, probably masgn?"
2714
+ ),
2715
+ constr
2716
+ ]
2717
+ end
2718
+
2719
+ pairs = block_params_.zip(method_type.block.type.params)
2720
+
2721
+ unless pairs
2722
+ return [
2723
+ Errors::IncompatibleBlockParameters.new(node: node, method_type: method_type),
2724
+ constr
2725
+ ]
2726
+ end
2727
+
2728
+ pairs.each do |param, type|
2729
+ if param.type
2730
+ check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
2731
+ return [
2732
+ Errors::IncompatibleAssignment.new(
2733
+ node: param.node,
2734
+ lhs_type: param.type,
2735
+ rhs_type: type,
2736
+ result: result
2737
+ ),
2738
+ constr
2739
+ ]
2740
+ end
2741
+ end
2536
2742
  end
2537
2743
  end
2538
2744
 
@@ -2683,7 +2889,7 @@ module Steep
2683
2889
  decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2684
2890
  hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2685
2891
  end
2686
- env.update(declared_types: env.declared_types.merge(decls))
2892
+ env.except(decls.keys).update(assigned_types: decls)
2687
2893
  end.annotate(block_annotations)
2688
2894
 
2689
2895
  break_type = if block_annotations.break_type
@@ -2826,7 +3032,7 @@ module Steep
2826
3032
  end
2827
3033
 
2828
3034
  def nested_namespace_for_module(module_name)
2829
- if module_name.relative?
3035
+ if module_name.namespace.relative?
2830
3036
  (current_namespace + module_name.namespace).append(module_name.name)
2831
3037
  else
2832
3038
  module_name
@@ -2835,7 +3041,7 @@ module Steep
2835
3041
 
2836
3042
  def absolute_name(module_name)
2837
3043
  if current_namespace
2838
- module_name.in_namespace(current_namespace)
3044
+ module_name.with_prefix(current_namespace)
2839
3045
  else
2840
3046
  module_name.absolute!
2841
3047
  end
@@ -2853,7 +3059,7 @@ module Steep
2853
3059
  end
2854
3060
 
2855
3061
  def validate_method_definitions(node, module_name)
2856
- module_name_1 = checker.factory.type_name_1(module_name.name)
3062
+ module_name_1 = module_name.name
2857
3063
  member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
2858
3064
 
2859
3065
  return unless member_decl_count == 1
@@ -3001,20 +3207,31 @@ module Steep
3001
3207
  end
3002
3208
  end
3003
3209
 
3004
- def deep_expand_alias(type, recursive: Set.new, &block)
3005
- raise "Recursive type definition: #{type}" if recursive.member?(type)
3210
+ def deep_expand_alias(type, &block)
3211
+ checker.factory.deep_expand_alias(type, &block)
3212
+ end
3006
3213
 
3007
- ty = case type
3008
- when AST::Types::Name::Alias
3009
- deep_expand_alias(expand_alias(type), recursive: recursive << type)
3010
- else
3011
- type
3012
- end
3214
+ def flatten_union(type)
3215
+ checker.factory.flatten_union(type)
3216
+ end
3013
3217
 
3014
- if block_given?
3015
- yield ty
3016
- else
3017
- ty
3218
+ def select_flatten_types(type, &block)
3219
+ types = flatten_union(deep_expand_alias(type))
3220
+ types.select(&block)
3221
+ end
3222
+
3223
+ def partition_flatten_types(type, &block)
3224
+ types = flatten_union(deep_expand_alias(type))
3225
+ types.partition(&block)
3226
+ end
3227
+
3228
+ def flatten_array_elements(type)
3229
+ flatten_union(deep_expand_alias(type)).flat_map do |type|
3230
+ if AST::Builtin::Array.instance_type?(type)
3231
+ type.args
3232
+ else
3233
+ [type]
3234
+ end
3018
3235
  end
3019
3236
  end
3020
3237
 
@@ -3056,8 +3273,8 @@ module Steep
3056
3273
 
3057
3274
  def to_instance_type(type, args: nil)
3058
3275
  args = args || case type
3059
- when AST::Types::Name::Class, AST::Types::Name::Module
3060
- checker.factory.env.class_decls[checker.factory.type_name_1(type.name)].type_params.each.map { AST::Builtin.any_type }
3276
+ when AST::Types::Name::Singleton
3277
+ checker.factory.env.class_decls[type.name].type_params.each.map { AST::Builtin.any_type }
3061
3278
  else
3062
3279
  raise "unexpected type to to_instance_type: #{type}"
3063
3280
  end
@@ -3065,6 +3282,47 @@ module Steep
3065
3282
  AST::Types::Name::Instance.new(name: type.name, args: args)
3066
3283
  end
3067
3284
 
3285
+ def try_tuple_type(node, hint)
3286
+ if node.children.size != hint.types.size
3287
+ return
3288
+ end
3289
+
3290
+ constr = self
3291
+ element_types = []
3292
+
3293
+ each_child_node(node).with_index do |child, index|
3294
+ type, constr = constr.synthesize(child, hint: hint.types[index])
3295
+ element_types << type
3296
+ end
3297
+
3298
+ constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
3299
+ end
3300
+
3301
+ def try_array_type(node, hint)
3302
+ element_hint = hint ? hint.args[0] : nil
3303
+
3304
+ constr = self
3305
+ element_types = []
3306
+
3307
+ each_child_node(node) do |child|
3308
+ case child.type
3309
+ when :splat
3310
+ type, constr = constr.synthesize(child.children[0], hint: hint)
3311
+ if AST::Builtin::Array.instance_type?(type)
3312
+ element_types << type.args[0]
3313
+ else
3314
+ element_types.push(*flatten_array_elements(type))
3315
+ end
3316
+ else
3317
+ type, constr = constr.synthesize(child, hint: element_hint)
3318
+ element_types << type
3319
+ end
3320
+ end
3321
+
3322
+ element_type = AST::Types::Union.build(types: element_types)
3323
+ constr.add_typing(node, type: AST::Builtin::Array.instance_type(element_type))
3324
+ end
3325
+
3068
3326
  def try_hash_type(node, hint)
3069
3327
  case hint
3070
3328
  when AST::Types::Record