steep 0.25.0 → 0.31.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -0
  3. data/bin/smoke_runner.rb +3 -4
  4. data/bin/steep-prof +1 -2
  5. data/lib/steep.rb +6 -4
  6. data/lib/steep/annotation_parser.rb +2 -4
  7. data/lib/steep/ast/builtin.rb +11 -21
  8. data/lib/steep/ast/types.rb +5 -3
  9. data/lib/steep/ast/types/any.rb +1 -3
  10. data/lib/steep/ast/types/boolean.rb +1 -3
  11. data/lib/steep/ast/types/bot.rb +1 -3
  12. data/lib/steep/ast/types/class.rb +2 -2
  13. data/lib/steep/ast/types/factory.rb +265 -90
  14. data/lib/steep/ast/types/helper.rb +6 -0
  15. data/lib/steep/ast/types/instance.rb +2 -2
  16. data/lib/steep/ast/types/intersection.rb +20 -13
  17. data/lib/steep/ast/types/literal.rb +1 -3
  18. data/lib/steep/ast/types/logic.rb +63 -0
  19. data/lib/steep/ast/types/name.rb +15 -67
  20. data/lib/steep/ast/types/nil.rb +1 -3
  21. data/lib/steep/ast/types/proc.rb +5 -2
  22. data/lib/steep/ast/types/record.rb +9 -4
  23. data/lib/steep/ast/types/self.rb +1 -1
  24. data/lib/steep/ast/types/top.rb +1 -3
  25. data/lib/steep/ast/types/tuple.rb +5 -3
  26. data/lib/steep/ast/types/union.rb +13 -9
  27. data/lib/steep/ast/types/var.rb +2 -2
  28. data/lib/steep/ast/types/void.rb +1 -3
  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.rb +25 -0
  35. data/lib/steep/project/completion_provider.rb +57 -58
  36. data/lib/steep/project/file_loader.rb +7 -2
  37. data/lib/steep/project/hover_content.rb +92 -83
  38. data/lib/steep/project/signature_file.rb +33 -0
  39. data/lib/steep/project/{file.rb → source_file.rb} +24 -54
  40. data/lib/steep/project/target.rb +31 -12
  41. data/lib/steep/server/base_worker.rb +5 -3
  42. data/lib/steep/server/code_worker.rb +31 -45
  43. data/lib/steep/server/interaction_worker.rb +42 -38
  44. data/lib/steep/server/master.rb +23 -31
  45. data/lib/steep/server/utils.rb +46 -13
  46. data/lib/steep/server/worker_process.rb +4 -2
  47. data/lib/steep/signature/validator.rb +3 -3
  48. data/lib/steep/source.rb +59 -2
  49. data/lib/steep/subtyping/check.rb +36 -50
  50. data/lib/steep/subtyping/constraints.rb +8 -0
  51. data/lib/steep/type_construction.rb +388 -366
  52. data/lib/steep/type_inference/block_params.rb +5 -0
  53. data/lib/steep/type_inference/constant_env.rb +2 -5
  54. data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
  55. data/lib/steep/type_inference/type_env.rb +2 -2
  56. data/lib/steep/version.rb +1 -1
  57. data/smoke/alias/a.rb +1 -1
  58. data/smoke/case/a.rb +1 -1
  59. data/smoke/hash/d.rb +1 -1
  60. data/smoke/if/a.rb +1 -1
  61. data/smoke/module/a.rb +1 -1
  62. data/smoke/rescue/a.rb +4 -13
  63. data/smoke/toplevel/Steepfile +5 -0
  64. data/smoke/toplevel/a.rb +4 -0
  65. data/smoke/toplevel/a.rbs +3 -0
  66. data/smoke/type_case/a.rb +0 -7
  67. data/steep.gemspec +3 -3
  68. metadata +17 -13
  69. data/lib/steep/ast/method_type.rb +0 -126
  70. data/lib/steep/ast/namespace.rb +0 -80
  71. data/lib/steep/names.rb +0 -86
@@ -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
@@ -777,11 +791,10 @@ module Steep
777
791
  synthesize(child)
778
792
  end
779
793
 
780
- super_method = Interface::Interface::Combination.overload(
781
- 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|
782
796
  checker.factory.method_type(method_type, self_type: self_type)
783
- },
784
- incompatible: false
797
+ }
785
798
  )
786
799
  args = TypeInference::SendArgs.from_nodes(node.children.dup)
787
800
 
@@ -877,10 +890,10 @@ module Steep
877
890
  self_type = expand_self(self_type)
878
891
  definition = case self_type
879
892
  when AST::Types::Name::Instance
880
- name = checker.factory.type_name_1(self_type.name)
893
+ name = self_type.name
881
894
  checker.factory.definition_builder.build_singleton(name)
882
- when AST::Types::Name::Module, AST::Types::Name::Class
883
- name = checker.factory.type_name_1(self_type.name)
895
+ when AST::Types::Name::Singleton
896
+ name = self_type.name
884
897
  checker.factory.definition_builder.build_singleton(name)
885
898
  end
886
899
 
@@ -1034,12 +1047,13 @@ module Steep
1034
1047
  var = node.children[0]
1035
1048
  rhs = node.children[1]
1036
1049
 
1037
- type = context.lvar_env[var.name]
1050
+ var_type = context.lvar_env[var.name]
1051
+ node_type, constr = synthesize(rhs, hint: var_type)
1038
1052
 
1039
- node_type, constr = synthesize(rhs, hint: type)
1053
+ type = AST::Types::Union.build(types: [var_type, node_type])
1040
1054
 
1041
1055
  constr_ = constr.update_lvar_env do |env|
1042
- 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|
1043
1057
  typing.add_error(
1044
1058
  Errors::IncompatibleAssignment.new(node: node,
1045
1059
  lhs_type: declared_type,
@@ -1049,7 +1063,7 @@ module Steep
1049
1063
  end
1050
1064
  end
1051
1065
 
1052
- add_typing(node, type: constr_.context.lvar_env[var.name], constr: constr_)
1066
+ add_typing(node, type: type, constr: constr_)
1053
1067
  end
1054
1068
 
1055
1069
  when :restarg
@@ -1229,6 +1243,17 @@ module Steep
1229
1243
  type, constr = synthesize(node.children[0])
1230
1244
  constructor = constr.for_sclass(node, type)
1231
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
+
1232
1257
  constructor.typing.add_context_for_node(node, context: constructor.context)
1233
1258
  constructor.typing.add_context_for_body(node, context: constructor.context)
1234
1259
 
@@ -1240,14 +1265,14 @@ module Steep
1240
1265
  end
1241
1266
  end
1242
1267
 
1243
- add_typing(node, type: AST::Builtin.nil_type)
1268
+ constr.add_typing(node, type: AST::Builtin.nil_type)
1244
1269
  end
1245
1270
 
1246
1271
  when :self
1247
1272
  add_typing node, type: AST::Types::Self.new
1248
1273
 
1249
1274
  when :const
1250
- const_name = Names::Module.from_node(node)
1275
+ const_name = module_name_from_node(node)
1251
1276
 
1252
1277
  if const_name
1253
1278
  type = type_env.get(const: const_name) do
@@ -1260,7 +1285,7 @@ module Steep
1260
1285
 
1261
1286
  when :casgn
1262
1287
  yield_self do
1263
- const_name = Names::Module.from_node(node)
1288
+ const_name = module_name_from_node(node)
1264
1289
  if const_name
1265
1290
  const_type = type_env.get(const: const_name) {}
1266
1291
  value_type = synthesize(node.children.last, hint: const_type).type
@@ -1373,15 +1398,17 @@ module Steep
1373
1398
  when :and
1374
1399
  yield_self do
1375
1400
  left, right = node.children
1376
- logic = TypeInference::Logic.new(subtyping: checker)
1377
- truthy, falsey = logic.nodes(node: left)
1378
1401
 
1379
1402
  left_type, constr = synthesize(left)
1380
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1381
- falsey_vars: falsey.vars,
1382
- lvar_env: constr.context.lvar_env)
1383
1403
 
1384
- 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)
1385
1412
 
1386
1413
  type = if left_type.is_a?(AST::Types::Boolean)
1387
1414
  union_type(left_type, right_type)
@@ -1403,16 +1430,18 @@ module Steep
1403
1430
  when :or
1404
1431
  yield_self do
1405
1432
  left, right = node.children
1406
- logic = TypeInference::Logic.new(subtyping: checker)
1407
- truthy, falsey = logic.nodes(node: left)
1408
1433
 
1409
1434
  left_type, constr = synthesize(left, hint: hint)
1410
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1411
- falsey_vars: falsey.vars,
1412
- lvar_env: constr.context.lvar_env)
1413
- left_type_t, _ = logic.partition_union(left_type)
1414
1435
 
1415
- 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)
1416
1445
 
1417
1446
  type = union_type(left_type_t, right_type)
1418
1447
 
@@ -1431,12 +1460,8 @@ module Steep
1431
1460
  cond, true_clause, false_clause = node.children
1432
1461
 
1433
1462
  cond_type, constr = synthesize(cond)
1434
- logic = TypeInference::Logic.new(subtyping: checker)
1435
-
1436
- truthys, falseys = logic.nodes(node: cond)
1437
- truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
1438
- falsey_vars: falseys.vars,
1439
- 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)
1440
1465
 
1441
1466
  if true_clause
1442
1467
  true_pair = constr
@@ -1486,90 +1511,109 @@ module Steep
1486
1511
  cond, *whens, els = node.children
1487
1512
 
1488
1513
  constr = self
1514
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1489
1515
 
1490
1516
  if cond
1491
- cond_type, constr = synthesize(cond)
1492
- cond_type = expand_alias(cond_type)
1493
- if cond_type.is_a?(AST::Types::Union)
1494
- var_names = TypeConstruction.value_variables(cond)
1495
- var_types = cond_type.types.dup
1496
- end
1497
- end
1517
+ branch_pairs = []
1518
+
1519
+ cond_type, constr = constr.synthesize(cond)
1520
+ _, cond_vars = interpreter.decompose_value(cond)
1521
+
1522
+ when_constr = constr
1523
+ whens.each do |clause|
1524
+ *tests, body = clause.children
1498
1525
 
1499
- branch_pairs = []
1526
+ test_constr = when_constr
1527
+ test_envs = []
1500
1528
 
1501
- whens.each do |clause|
1502
- *tests, body = clause.children
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) }
1503
1538
 
1504
- test_types = []
1505
- clause_constr = constr
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
1506
1547
 
1507
- tests.each do |test|
1508
- type, clause_constr = synthesize(test)
1509
- test_types << expand_alias(type)
1548
+ when_constr = test_constr
1510
1549
  end
1511
1550
 
1512
- if body
1513
- if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Class) }
1514
- var_types_in_body = test_types.flat_map do |test_type|
1515
- filtered_types = var_types.select do |var_type|
1516
- var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
1517
- end
1518
- if filtered_types.empty?
1519
- to_instance_type(test_type)
1520
- else
1521
- filtered_types
1522
- end
1523
- 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)
1524
1555
 
1525
- var_types.reject! do |type|
1526
- var_types_in_body.any? do |test_type|
1527
- type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1528
- end
1529
- end
1556
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1557
+ end
1530
1558
 
1531
- var_type_in_body = union_type(*var_types_in_body)
1532
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1533
- hash[var_name] = var_type_in_body
1534
- end
1559
+ types = branch_pairs.map(&:type)
1560
+ constrs = branch_pairs.map(&:constr)
1535
1561
 
1536
- branch_pairs << clause_constr
1537
- .for_branch(body, type_case_override: type_case_override)
1538
- .synthesize(body, hint: hint)
1539
- else
1540
- 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)
1541
1570
  end
1542
1571
  else
1543
- branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1572
+ unless els
1573
+ types << AST::Builtin.nil_type
1574
+ end
1544
1575
  end
1545
- end
1576
+ else
1577
+ branch_pairs = []
1578
+
1579
+ when_constr = constr
1580
+
1581
+ whens.each do |clause|
1582
+ *tests, body = clause.children
1583
+
1584
+ test_constr = when_constr
1585
+ test_envs = []
1546
1586
 
1547
- if els
1548
- if var_names && var_types
1549
- if var_types.empty?
1550
- typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
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 }
1551
1592
  end
1552
1593
 
1553
- else_override = var_names.each.with_object({}) do |var_name, hash|
1554
- hash[var_name] = unless var_types.empty?
1555
- union_type(*var_types)
1556
- else
1557
- AST::Builtin.any_type
1558
- 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)
1559
1604
  end
1560
- branch_pairs << constr
1561
- .for_branch(els, type_case_override: else_override)
1562
- .synthesize(els, hint: hint)
1563
- else
1564
- branch_pairs << constr.synthesize(els, hint: hint)
1565
1605
  end
1566
- end
1567
1606
 
1568
- types = branch_pairs.map(&:type)
1569
- 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)
1570
1613
 
1571
- unless var_types&.empty? || els
1572
- types.push AST::Builtin.nil_type
1614
+ unless els
1615
+ types << AST::Builtin.nil_type
1616
+ end
1573
1617
  end
1574
1618
 
1575
1619
  constr = constr.update_lvar_env do |env|
@@ -1582,7 +1626,7 @@ module Steep
1582
1626
  when :rescue
1583
1627
  yield_self do
1584
1628
  body, *resbodies, else_node = node.children
1585
- body_pair = synthesize(body) if body
1629
+ body_pair = synthesize(body, hint: hint) if body
1586
1630
 
1587
1631
  body_constr = if body_pair
1588
1632
  self.update_lvar_env do |env|
@@ -1620,7 +1664,7 @@ module Steep
1620
1664
  instance_types = exn_types.map do |type|
1621
1665
  type = expand_alias(type)
1622
1666
  case
1623
- when type.is_a?(AST::Types::Name::Class)
1667
+ when type.is_a?(AST::Types::Name::Singleton)
1624
1668
  to_instance_type(type)
1625
1669
  else
1626
1670
  AST::Builtin.any_type
@@ -1634,7 +1678,7 @@ module Steep
1634
1678
  resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
1635
1679
 
1636
1680
  if body
1637
- resbody_construction.synthesize(body)
1681
+ resbody_construction.synthesize(body, hint: hint)
1638
1682
  else
1639
1683
  Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
1640
1684
  end
@@ -1644,7 +1688,7 @@ module Steep
1644
1688
  resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
1645
1689
 
1646
1690
  if else_node
1647
- 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)
1648
1692
  add_typing(node,
1649
1693
  type: union_type(*[else_pair.type, *resbody_types].compact),
1650
1694
  constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
@@ -1660,7 +1704,7 @@ module Steep
1660
1704
  klasses, asgn, body = node.children
1661
1705
  synthesize(klasses) if klasses
1662
1706
  synthesize(asgn) if asgn
1663
- body_type = synthesize(body).type if body
1707
+ body_type = synthesize(body, hint: hint).type if body
1664
1708
  add_typing(node, type: body_type)
1665
1709
  end
1666
1710
 
@@ -1687,7 +1731,7 @@ module Steep
1687
1731
  AST::Types::Any.new
1688
1732
  else
1689
1733
  each = checker.factory.interface(collection_type, private: true).methods[:each]
1690
- method_type = (each&.types || []).find {|type| type.block && type.block.type.params.first_param }
1734
+ method_type = (each&.method_types || []).find {|type| type.block && type.block.type.params.first_param }
1691
1735
  method_type&.yield_self do |method_type|
1692
1736
  method_type.block.type.params.first_param&.type
1693
1737
  end
@@ -1721,16 +1765,16 @@ module Steep
1721
1765
  when :while, :until
1722
1766
  yield_self do
1723
1767
  cond, body = node.children
1724
- _, constr = synthesize(cond)
1768
+ cond_type, constr = synthesize(cond)
1725
1769
 
1726
- logic = TypeInference::Logic.new(subtyping: checker)
1727
- 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)
1728
1772
 
1729
1773
  case node.type
1730
1774
  when :while
1731
- 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
1732
1776
  when :until
1733
- 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
1734
1778
  end
1735
1779
 
1736
1780
  if body
@@ -1779,9 +1823,22 @@ module Steep
1779
1823
  end
1780
1824
 
1781
1825
  when :irange, :erange
1782
- types = node.children.map {|n| synthesize(n).type }
1783
- type = AST::Builtin::Range.instance_type(union_type(*types))
1784
- 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)
1785
1842
 
1786
1843
  when :regexp
1787
1844
  each_child_node(node) do |child|
@@ -1800,13 +1857,34 @@ module Steep
1800
1857
  when :or_asgn, :and_asgn
1801
1858
  yield_self do
1802
1859
  asgn, rhs = node.children
1803
- type, constr = synthesize(rhs, hint: hint)
1804
1860
 
1805
1861
  case asgn.type
1806
1862
  when :lvasgn
1863
+ type, constr = synthesize(rhs, hint: hint)
1807
1864
  constr.lvasgn(asgn, type)
1808
1865
  when :ivasgn
1866
+ type, constr = synthesize(rhs, hint: hint)
1809
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)
1810
1888
  end
1811
1889
  end
1812
1890
 
@@ -1854,8 +1932,8 @@ module Steep
1854
1932
  param_type = hint.params.required[0]
1855
1933
  interface = checker.factory.interface(param_type, private: true)
1856
1934
  method = interface.methods[value.children[0]]
1857
- if method&.overload?
1858
- return_types = method.types.select {|method_type|
1935
+ if method
1936
+ return_types = method.method_types.select {|method_type|
1859
1937
  method_type.params.each_type.count == 0
1860
1938
  }.map(&:return_type)
1861
1939
 
@@ -1935,8 +2013,18 @@ module Steep
1935
2013
  add_typing node, type: AST::Builtin.any_type
1936
2014
  end
1937
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
+
1938
2025
  else
1939
2026
  raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
2027
+
1940
2028
  end.tap do |pair|
1941
2029
  unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
1942
2030
  # Steep.logger.error { "result = #{pair.inspect}" }
@@ -2199,7 +2287,7 @@ module Steep
2199
2287
 
2200
2288
  def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2201
2289
  receiver, method_name, *arguments = send_node.children
2202
- receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
2290
+ receiver_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2203
2291
 
2204
2292
  if unwrap
2205
2293
  receiver_type = unwrap(receiver_type)
@@ -2207,74 +2295,80 @@ module Steep
2207
2295
 
2208
2296
  receiver_type = expand_alias(receiver_type)
2209
2297
 
2210
- pair = case receiver_type
2211
- when AST::Types::Any
2212
- 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
2213
2305
 
2214
- when nil
2215
- fallback_to_any node
2306
+ add_typing node, type: AST::Builtin.any_type
2216
2307
 
2217
- when AST::Types::Void, AST::Types::Bot, AST::Types::Top
2218
- fallback_to_any node do
2219
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2220
- end
2308
+ when nil
2309
+ fallback_to_any node
2221
2310
 
2222
- else
2223
- case expanded_receiver_type = expand_self(receiver_type)
2224
- when AST::Types::Self
2225
- Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
2226
- fallback_to_any node do
2227
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2228
- end
2229
- else
2230
- begin
2231
- interface = checker.factory.interface(receiver_type,
2232
- private: !receiver,
2233
- self_type: expanded_receiver_type)
2234
-
2235
- method = interface.methods[method_name]
2236
-
2237
- if method
2238
- args = TypeInference::SendArgs.from_nodes(arguments)
2239
- return_type, constr, _ = type_method_call(node,
2240
- method: method,
2241
- method_name: method_name,
2242
- args: args,
2243
- block_params: block_params,
2244
- block_body: block_body,
2245
- receiver_type: receiver_type,
2246
- topdown_hint: true)
2247
-
2248
- add_typing node, type: return_type, constr: constr
2249
- else
2250
- fallback_to_any node do
2251
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2252
- end
2253
- end
2254
- rescue => exn
2255
- case exn
2256
- when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2257
- # ignore known RBS errors.
2258
- else
2259
- Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2260
- 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
2261
2315
 
2262
- fallback_to_any node do
2263
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2264
- end
2265
- end
2266
- end
2267
- 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
2268
2355
 
2269
- case pair.type
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
2362
+
2363
+ case type
2270
2364
  when nil, Errors::Base
2271
2365
  arguments.each do |arg|
2272
2366
  unless typing.has_type?(arg)
2273
2367
  if arg.type == :splat
2274
- type = synthesize(arg.children[0]).type
2368
+ type, constr = constr.synthesize(arg.children[0])
2275
2369
  add_typing(arg, type: AST::Builtin::Array.instance_type(type))
2276
2370
  else
2277
- synthesize(arg)
2371
+ _, constr = constr.synthesize(arg)
2278
2372
  end
2279
2373
  end
2280
2374
  end
@@ -2296,7 +2390,7 @@ module Steep
2296
2390
  end
2297
2391
  end
2298
2392
  else
2299
- pair
2393
+ Pair.new(type: type, constr: constr)
2300
2394
  end
2301
2395
  end
2302
2396
 
@@ -2363,139 +2457,68 @@ module Steep
2363
2457
  def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
2364
2458
  node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
2365
2459
 
2366
- case
2367
- when method.union?
2368
- yield_self do
2369
- 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|
2370
2465
  typing.new_child(node_range) do |child_typing|
2371
- with_new_typing(child_typing).type_method_call(node,
2372
- method_name: method_name,
2373
- receiver_type: receiver_type,
2374
- method: method,
2375
- args: args,
2376
- block_params: block_params,
2377
- block_body: block_body,
2378
- topdown_hint: false)
2379
- end
2380
- 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
+ )
2381
2477
 
2382
- if (type, constr, error = results.find {|_, _, error| error })
2383
- constr.typing.save!
2384
- [type,
2385
- update_lvar_env { constr.context.lvar_env },
2386
- error]
2387
- else
2388
- types = results.map(&:first)
2478
+ raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2389
2479
 
2390
- _, constr, _ = results.first
2391
- constr.typing.save!
2480
+ result, constr = ret
2392
2481
 
2393
- [union_type(*types),
2394
- update_lvar_env { constr.context.lvar_env },
2395
- nil]
2482
+ [result, constr, method_type]
2483
+ end
2396
2484
  end
2397
2485
  end
2486
+ end
2398
2487
 
2399
- when method.intersection?
2400
- yield_self do
2401
- results = method.types.map do |method|
2402
- typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2403
- 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),
2404
2510
  method_name: method_name,
2405
- receiver_type: receiver_type,
2406
- method: method,
2407
- args: args,
2408
- block_params: block_params,
2409
- block_body: block_body,
2410
- topdown_hint: false)
2411
- end
2412
- end
2413
-
2414
- successes = results.reject {|_, _, error| error }
2415
- unless successes.empty?
2416
- types = successes.map(&:first)
2417
- constr = successes[0][1]
2418
- constr.typing.save!
2419
-
2420
- [AST::Types::Intersection.build(types: types),
2421
- update_lvar_env { constr.context.lvar_env },
2422
- nil]
2423
- else
2424
- type, constr, error = results.first
2425
- constr.typing.save!
2426
-
2427
- [type,
2428
- update_lvar_env { constr.context.lvar_env },
2429
- error]
2430
- end
2511
+ method_types: method.method_types)
2512
+ type = AST::Builtin.any_type
2431
2513
  end
2432
2514
 
2433
- when method.overload?
2434
- yield_self do
2435
- results = method.types.flat_map do |method_type|
2436
- Steep.logger.tagged method_type.to_s do
2437
- zips = args.zips(method_type.params, method_type.block&.type)
2438
-
2439
- zips.map do |arg_pairs|
2440
- typing.new_child(node_range) do |child_typing|
2441
- ret = self.with_new_typing(child_typing).try_method_type(
2442
- node,
2443
- receiver_type: receiver_type,
2444
- method_type: method_type,
2445
- args: args,
2446
- arg_pairs: arg_pairs,
2447
- block_params: block_params,
2448
- block_body: block_body,
2449
- child_typing: child_typing,
2450
- topdown_hint: topdown_hint
2451
- )
2452
-
2453
- raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2454
-
2455
- result, constr = ret
2456
-
2457
- [result, constr, method_type]
2458
- end
2459
- end
2460
- end
2461
- end
2462
-
2463
- unless results.empty?
2464
- result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2465
- else
2466
- method_type = method.types.last
2467
- constr = self.with_new_typing(typing.new_child(node_range))
2468
- result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
2469
- end
2470
- constr.typing.save!
2471
-
2472
- case result
2473
- when Errors::Base
2474
- if method.types.size == 1
2475
- typing.add_error result
2476
- type = case method_type.return_type
2477
- when AST::Types::Var
2478
- AST::Builtin.any_type
2479
- else
2480
- method_type.return_type
2481
- end
2482
- else
2483
- typing.add_error Errors::UnresolvedOverloading.new(node: node,
2484
- receiver_type: expand_self(receiver_type),
2485
- method_name: method_name,
2486
- method_types: method.types)
2487
- type = AST::Builtin.any_type
2488
- end
2489
-
2490
- [type,
2491
- update_lvar_env { constr.context.lvar_env },
2492
- result]
2493
- else # Type
2494
- [result,
2495
- update_lvar_env { constr.context.lvar_env },
2496
- nil]
2497
- end
2498
- 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]
2499
2522
  end
2500
2523
  end
2501
2524
 
@@ -2682,16 +2705,40 @@ module Steep
2682
2705
  if block_params && method_type.block
2683
2706
  block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2684
2707
  block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2685
- block_param_hint = block_params_.params_type(
2686
- hint: topdown_hint ? method_type.block.type.params : nil
2687
- )
2688
2708
 
2689
- check_relation(sub_type: AST::Types::Proc.new(params: block_param_hint, return_type: AST::Types::Any.new),
2690
- super_type: method_type.block.type,
2691
- constraints: constraints).else do |result|
2692
- return [Errors::IncompatibleBlockParameters.new(node: node,
2693
- method_type: method_type),
2694
- 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
2695
2742
  end
2696
2743
  end
2697
2744
 
@@ -2842,7 +2889,7 @@ module Steep
2842
2889
  decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2843
2890
  hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2844
2891
  end
2845
- env.update(declared_types: env.declared_types.merge(decls))
2892
+ env.except(decls.keys).update(assigned_types: decls)
2846
2893
  end.annotate(block_annotations)
2847
2894
 
2848
2895
  break_type = if block_annotations.break_type
@@ -2985,7 +3032,7 @@ module Steep
2985
3032
  end
2986
3033
 
2987
3034
  def nested_namespace_for_module(module_name)
2988
- if module_name.relative?
3035
+ if module_name.namespace.relative?
2989
3036
  (current_namespace + module_name.namespace).append(module_name.name)
2990
3037
  else
2991
3038
  module_name
@@ -2994,7 +3041,7 @@ module Steep
2994
3041
 
2995
3042
  def absolute_name(module_name)
2996
3043
  if current_namespace
2997
- module_name.in_namespace(current_namespace)
3044
+ module_name.with_prefix(current_namespace)
2998
3045
  else
2999
3046
  module_name.absolute!
3000
3047
  end
@@ -3012,7 +3059,7 @@ module Steep
3012
3059
  end
3013
3060
 
3014
3061
  def validate_method_definitions(node, module_name)
3015
- module_name_1 = checker.factory.type_name_1(module_name.name)
3062
+ module_name_1 = module_name.name
3016
3063
  member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
3017
3064
 
3018
3065
  return unless member_decl_count == 1
@@ -3160,37 +3207,12 @@ module Steep
3160
3207
  end
3161
3208
  end
3162
3209
 
3163
- def deep_expand_alias(type, recursive: Set.new, &block)
3164
- raise "Recursive type definition: #{type}" if recursive.member?(type)
3165
-
3166
- ty = case type
3167
- when AST::Types::Name::Alias
3168
- deep_expand_alias(expand_alias(type), recursive: recursive.union([type]))
3169
- when AST::Types::Union
3170
- AST::Types::Union.build(
3171
- types: type.types.map {|ty| deep_expand_alias(ty, recursive: recursive, &block) },
3172
- location: type.location
3173
- )
3174
- else
3175
- type
3176
- end
3177
-
3178
- if block_given?
3179
- yield ty
3180
- else
3181
- ty
3182
- end
3210
+ def deep_expand_alias(type, &block)
3211
+ checker.factory.deep_expand_alias(type, &block)
3183
3212
  end
3184
3213
 
3185
- def flatten_union(type, acc = [])
3186
- case type
3187
- when AST::Types::Union
3188
- type.types.each {|ty| flatten_union(ty, acc) }
3189
- else
3190
- acc << type
3191
- end
3192
-
3193
- acc
3214
+ def flatten_union(type)
3215
+ checker.factory.flatten_union(type)
3194
3216
  end
3195
3217
 
3196
3218
  def select_flatten_types(type, &block)
@@ -3251,8 +3273,8 @@ module Steep
3251
3273
 
3252
3274
  def to_instance_type(type, args: nil)
3253
3275
  args = args || case type
3254
- when AST::Types::Name::Class, AST::Types::Name::Module
3255
- 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 }
3256
3278
  else
3257
3279
  raise "unexpected type to to_instance_type: #{type}"
3258
3280
  end