steep 1.4.0.dev.2 → 1.4.0.dev.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -2
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +9 -11
  5. data/Gemfile.steep +1 -2
  6. data/Gemfile.steep.lock +11 -14
  7. data/README.md +7 -1
  8. data/Steepfile +0 -3
  9. data/bin/rbs +0 -1
  10. data/guides/README.md +5 -0
  11. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +143 -0
  12. data/guides/src/getting-started/getting-started.md +164 -0
  13. data/guides/src/nil-optional/nil-optional.md +195 -0
  14. data/lib/steep/diagnostic/ruby.rb +80 -6
  15. data/lib/steep/drivers/check.rb +4 -4
  16. data/lib/steep/interface/block.rb +10 -0
  17. data/lib/steep/interface/builder.rb +3 -3
  18. data/lib/steep/method_name.rb +8 -0
  19. data/lib/steep/module_helper.rb +13 -11
  20. data/lib/steep/path_helper.rb +4 -0
  21. data/lib/steep/server/interaction_worker.rb +197 -230
  22. data/lib/steep/server/lsp_formatter.rb +308 -154
  23. data/lib/steep/server/master.rb +4 -1
  24. data/lib/steep/services/completion_provider.rb +140 -103
  25. data/lib/steep/services/hover_provider/rbs.rb +37 -32
  26. data/lib/steep/services/signature_help_provider.rb +108 -0
  27. data/lib/steep/services/type_name_completion.rb +165 -0
  28. data/lib/steep/source.rb +1 -0
  29. data/lib/steep/type_construction.rb +460 -266
  30. data/lib/steep/type_inference/block_params.rb +13 -0
  31. data/lib/steep/type_inference/context.rb +3 -3
  32. data/lib/steep/type_inference/method_call.rb +1 -1
  33. data/lib/steep/type_inference/method_params.rb +42 -16
  34. data/lib/steep/type_inference/send_args.rb +80 -51
  35. data/lib/steep/type_inference/type_env.rb +12 -4
  36. data/lib/steep/version.rb +1 -1
  37. data/lib/steep.rb +2 -0
  38. data/rbs_collection.steep.lock.yaml +0 -28
  39. data/rbs_collection.steep.yaml +10 -9
  40. data/sample/Steepfile +2 -0
  41. data/sample/lib/conference.rb +12 -0
  42. data/sample/sig/conference.rbs +5 -0
  43. data/sig/shims/language-server_protocol.rbs +277 -0
  44. data/sig/shims/parser/nodes.rbs +37 -0
  45. data/sig/shims/parser.rbs +4 -0
  46. data/sig/shims/string.rbs +4 -0
  47. data/sig/steep/ast/types/factory.rbs +10 -8
  48. data/sig/steep/diagnostic/lsp_formatter.rbs +1 -1
  49. data/sig/steep/diagnostic/ruby.rbs +38 -2
  50. data/sig/steep/drivers/check.rbs +1 -1
  51. data/sig/steep/drivers/checkfile.rbs +1 -1
  52. data/sig/steep/drivers/diagnostic_printer.rbs +1 -1
  53. data/sig/steep/drivers/watch.rbs +1 -1
  54. data/sig/steep/index/signature_symbol_provider.rbs +1 -1
  55. data/sig/steep/interface/block.rbs +2 -0
  56. data/sig/steep/interface/builder.rbs +5 -3
  57. data/sig/steep/interface/method_type.rbs +5 -3
  58. data/sig/steep/method_name.rbs +5 -1
  59. data/sig/steep/module_helper.rbs +9 -0
  60. data/sig/steep/path_helper.rbs +3 -1
  61. data/sig/steep/server/base_worker.rbs +1 -1
  62. data/sig/steep/server/interaction_worker.rbs +52 -17
  63. data/sig/steep/server/lsp_formatter.rbs +43 -18
  64. data/sig/steep/server/master.rbs +1 -1
  65. data/sig/steep/server/type_check_worker.rbs +7 -5
  66. data/sig/steep/server/worker_process.rbs +6 -4
  67. data/sig/steep/services/completion_provider.rbs +106 -28
  68. data/sig/steep/services/hover_provider/rbs.rbs +13 -9
  69. data/sig/steep/services/signature_help_provider.rbs +39 -0
  70. data/sig/steep/services/type_name_completion.rbs +122 -0
  71. data/sig/steep/type_construction.rbs +99 -30
  72. data/sig/steep/type_inference/block_params.rbs +4 -0
  73. data/sig/steep/type_inference/context.rbs +70 -22
  74. data/sig/steep/type_inference/method_call.rbs +1 -1
  75. data/sig/steep/type_inference/method_params.rbs +43 -24
  76. data/sig/steep/type_inference/multiple_assignment.rbs +1 -1
  77. data/sig/steep/type_inference/send_args.rbs +19 -5
  78. data/sig/steep/typing.rbs +8 -3
  79. data/smoke/diagnostics/test_expectations.yml +1 -0
  80. data/steep.gemspec +0 -1
  81. metadata +12 -16
@@ -52,10 +52,6 @@ module Steep
52
52
  context.module_context
53
53
  end
54
54
 
55
- def module_context!
56
- module_context or raise
57
- end
58
-
59
55
  def method_context
60
56
  context.method_context
61
57
  end
@@ -68,6 +64,10 @@ module Steep
68
64
  context.block_context
69
65
  end
70
66
 
67
+ def block_context!
68
+ block_context or raise
69
+ end
70
+
71
71
  def break_context
72
72
  context.break_context
73
73
  end
@@ -135,8 +135,8 @@ module Steep
135
135
  checker.check(
136
136
  relation,
137
137
  self_type: self_type,
138
- instance_type: module_context!.instance_type,
139
- class_type: module_context!.module_type,
138
+ instance_type: module_context.instance_type,
139
+ class_type: module_context.module_type,
140
140
  constraints: constraints
141
141
  )
142
142
  end
@@ -163,8 +163,8 @@ module Steep
163
163
 
164
164
  method_type = annotation_method_type || definition_method_type
165
165
 
166
- if annots&.return_type && method_type&.type&.return_type
167
- check_relation(sub_type: annots.return_type, super_type: method_type.type.return_type).else do |result|
166
+ if (annotation_return_type = annots&.return_type) && (method_type_return_type = method_type&.type&.return_type)
167
+ check_relation(sub_type: annotation_return_type, super_type: method_type_return_type).else do |result|
168
168
  typing.add_error(
169
169
  Diagnostic::Ruby::MethodReturnTypeAnnotationMismatch.new(
170
170
  node: node,
@@ -194,23 +194,23 @@ module Steep
194
194
  variable_context = self.variable_context
195
195
  end
196
196
 
197
+ method_params =
198
+ if method_type
199
+ TypeInference::MethodParams.build(node: node, method_type: method_type)
200
+ else
201
+ TypeInference::MethodParams.empty(node: node)
202
+ end
203
+
197
204
  method_context = TypeInference::Context::MethodContext.new(
198
205
  name: method_name,
199
206
  method: definition && definition.methods[method_name],
200
207
  method_type: method_type,
201
208
  return_type: annots.return_type || method_type&.type&.return_type || AST::Builtin.any_type,
202
- constructor: false,
203
- super_method: super_method
209
+ super_method: super_method,
210
+ forward_arg_type: method_params.forward_arg_type
204
211
  )
205
212
 
206
- method_params =
207
- if method_type
208
- TypeInference::MethodParams.build(node: node, method_type: method_type)
209
- else
210
- TypeInference::MethodParams.empty(node: node)
211
- end
212
-
213
- local_variable_types = method_params.each_param.with_object({}) do |param, hash|
213
+ local_variable_types = method_params.each_param.with_object({}) do |param, hash| #$ Hash[Symbol, AST::Types::t]
214
214
  if param.name
215
215
  unless SPECIAL_LVAR_NAMES.include?(param.name)
216
216
  hash[param.name] = param.var_type
@@ -221,14 +221,16 @@ module Steep
221
221
 
222
222
  type_env = TypeInference::TypeEnvBuilder.new(
223
223
  TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annots).merge!.on_duplicate! do |name, original, annotated|
224
- param = method_params.each_param.find {|param| param.name == name }
225
- if result = no_subtyping?(sub_type: original, super_type: annotated)
226
- typing.add_error Diagnostic::Ruby::IncompatibleAnnotation.new(
227
- node: param.node,
228
- var_name: name,
229
- result: result,
230
- relation: result.relation
231
- )
224
+ if method_params.param?(name)
225
+ param = method_params[name]
226
+ if result = no_subtyping?(sub_type: original, super_type: annotated)
227
+ typing.add_error Diagnostic::Ruby::IncompatibleAnnotation.new(
228
+ node: param.node,
229
+ var_name: name,
230
+ result: result,
231
+ relation: result.relation
232
+ )
233
+ end
232
234
  end
233
235
  end,
234
236
  TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(definition, checker.factory),
@@ -308,7 +310,7 @@ module Steep
308
310
 
309
311
  def default_module_context(implement_module_name, nesting:)
310
312
  if implement_module_name
311
- module_name = checker.factory.absolute_type_name(implement_module_name.name, context: nesting)
313
+ module_name = checker.factory.absolute_type_name(implement_module_name.name, context: nesting) or raise
312
314
  module_args = implement_module_name.args.map {|name| AST::Types::Var.new(name: name) }
313
315
 
314
316
  instance_def = checker.factory.definition_builder.build_instance(module_name)
@@ -328,8 +330,8 @@ module Steep
328
330
  )
329
331
  else
330
332
  TypeInference::Context::ModuleContext.new(
331
- instance_type: nil,
332
- module_type: nil,
333
+ instance_type: AST::Builtin::Object.instance_type,
334
+ module_type: AST::Builtin::Object.module_type,
333
335
  implement_name: nil,
334
336
  nesting: nesting,
335
337
  class_name: self.module_context.class_name,
@@ -375,6 +377,8 @@ module Steep
375
377
  args: module_self.args,
376
378
  location: module_self.location
377
379
  )
380
+ else
381
+ raise
378
382
  end
379
383
  checker.factory.type(type)
380
384
  },
@@ -451,7 +455,7 @@ module Steep
451
455
  end
452
456
 
453
457
  def for_class(node, new_class_name, super_class_name)
454
- new_nesting = [nesting, new_class_name || false]
458
+ new_nesting = [nesting, new_class_name || false] #: RBS::Resolver::context
455
459
  annots = source.annotations(block: node, factory: checker.factory, context: new_nesting)
456
460
 
457
461
  class_const_env = TypeInference::ConstantEnv.new(
@@ -594,7 +598,7 @@ module Steep
594
598
 
595
599
  module_definition = case module_type
596
600
  when AST::Types::Name::Singleton
597
- type_name = instance_type.name
601
+ type_name = module_type.name
598
602
  checker.factory.definition_builder.build_singleton(type_name)
599
603
  else
600
604
  nil
@@ -728,7 +732,7 @@ module Steep
728
732
  else
729
733
  if enforced_type = context.type_env.enforced_type(name)
730
734
  case
731
- when hint == nil
735
+ when !hint
732
736
  hint = enforced_type
733
737
  when check_relation(sub_type: enforced_type, super_type: hint).success?
734
738
  # enforced_type is compatible with hint and more specific to hint.
@@ -862,27 +866,29 @@ module Steep
862
866
 
863
867
  when :super
864
868
  yield_self do
865
- if self_type && method_context&.method
866
- if super_def = method_context.super_method
869
+ if self_type && method_context!.method
870
+ if super_def = method_context!.super_method
867
871
  each_child_node(node) do |child|
868
872
  synthesize(child)
869
873
  end
870
874
 
871
875
  super_method = Interface::Shape::Entry.new(
872
- method_types: method_context.super_method.method_types.map {|method_type|
876
+ method_types: super_def.defs.map {|type_def|
873
877
  decl = TypeInference::MethodCall::MethodDecl.new(
874
- method_name: InstanceMethodName.new(type_name: super_def.implemented_in || super_def.defined_in,
875
- method_name: method_context.name),
876
- method_def: super_def
878
+ method_name: InstanceMethodName.new(
879
+ type_name: super_def.implemented_in || super_def.defined_in || raise,
880
+ method_name: method_context!.name || raise("method context must have a name")
881
+ ),
882
+ method_def: type_def
877
883
  )
878
- checker.factory.method_type(method_type, method_decls: Set[decl])
884
+ checker.factory.method_type(type_def.type, method_decls: Set[decl])
879
885
  }
880
886
  )
881
887
 
882
888
  call, constr = type_method_call(
883
889
  node,
884
890
  receiver_type: self_type,
885
- method_name: method_context.name,
891
+ method_name: method_context!.name || raise("method context must have a name"),
886
892
  method: super_method,
887
893
  arguments: node.children,
888
894
  block_params: nil,
@@ -896,13 +902,13 @@ module Steep
896
902
  error = Diagnostic::Ruby::UnresolvedOverloading.new(
897
903
  node: node,
898
904
  receiver_type: self_type,
899
- method_name: method_context.name,
905
+ method_name: method_context!.name,
900
906
  method_types: super_method.method_types
901
907
  )
902
908
  call = TypeInference::MethodCall::Error.new(
903
909
  node: node,
904
- context: context.method_context,
905
- method_name: method_context.name,
910
+ context: context.call_context,
911
+ method_name: method_context!.name || raise("method context must have a name"),
906
912
  receiver_type: self_type,
907
913
  errors: [error]
908
914
  )
@@ -913,7 +919,7 @@ module Steep
913
919
  end
914
920
  else
915
921
  fallback_to_any node do
916
- Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context.name)
922
+ Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context!.name)
917
923
  end
918
924
  end
919
925
  else
@@ -923,6 +929,8 @@ module Steep
923
929
 
924
930
  when :def
925
931
  yield_self do
932
+ # @type var node: Parser::AST::Node & Parser::AST::_DefNode
933
+
926
934
  name, args_node, body_node = node.children
927
935
 
928
936
  with_method_constr(
@@ -1021,16 +1029,16 @@ module Steep
1021
1029
  new.typing.add_context_for_node(node, context: new.context)
1022
1030
  new.typing.add_context_for_body(node, context: new.context)
1023
1031
 
1024
- new.method_context.tap do |method_context|
1032
+ new.method_context!.tap do |method_context|
1025
1033
  if method_context.method
1026
1034
  name_ = node.children[1]
1027
1035
 
1028
1036
  method_name =
1029
1037
  case self_type
1030
1038
  when AST::Types::Name::Instance
1031
- InstanceMethodName.new(type_name: method_context.method.implemented_in, method_name: name_)
1039
+ InstanceMethodName.new(type_name: method_context.method.implemented_in || raise, method_name: name_)
1032
1040
  when AST::Types::Name::Singleton
1033
- SingletonMethodName.new(type_name: method_context.method.implemented_in, method_name: name_)
1041
+ SingletonMethodName.new(type_name: method_context.method.implemented_in || raise, method_name: name_)
1034
1042
  end
1035
1043
 
1036
1044
  new.typing.source_index.add_definition(method: method_name, definition: node)
@@ -1044,8 +1052,8 @@ module Steep
1044
1052
  end
1045
1053
 
1046
1054
  if node.children[3]
1047
- return_type = expand_alias(new.method_context&.return_type)
1048
- if return_type && !return_type.is_a?(AST::Types::Void)
1055
+ return_type = expand_alias(new.method_context!.return_type)
1056
+ if !return_type.is_a?(AST::Types::Void)
1049
1057
  new.check(node.children[3], return_type) do |return_type, actual_type, result|
1050
1058
  typing.add_error(
1051
1059
  Diagnostic::Ruby::MethodBodyTypeMismatch.new(
@@ -1062,49 +1070,44 @@ module Steep
1062
1070
  end
1063
1071
  end
1064
1072
 
1065
- if module_context
1066
- if node.children[0].type == :self
1067
- module_context.defined_module_methods << node.children[1]
1068
- end
1073
+ if node.children[0].type == :self
1074
+ module_context.defined_module_methods << node.children[1]
1069
1075
  end
1070
1076
 
1071
1077
  add_typing(node, type: AST::Builtin::Symbol.instance_type)
1072
1078
 
1073
1079
  when :return
1074
1080
  yield_self do
1075
- method_return_type = expand_alias(method_context&.return_type)
1081
+ method_return_type =
1082
+ if method_context
1083
+ expand_alias(method_context.return_type)
1084
+ end
1076
1085
 
1077
- if node.children.size > 0
1086
+ case node.children.size
1087
+ when 0
1088
+ value_type = AST::Builtin.nil_type
1089
+ constr = self
1090
+ when 1
1091
+ return_value_node = node.children[0]
1092
+ value_type, constr = synthesize(return_value_node, hint: method_return_type)
1093
+ else
1094
+ constr = synthesize_children(node)
1078
1095
  return_types = node.children.map do |value|
1079
- synthesize(
1080
- value,
1081
- hint: if method_return_type.is_a?(AST::Types::Void)
1082
- nil
1083
- else
1084
- method_return_type
1085
- end
1086
- ).type
1096
+ constr.typing.type_of(node: value)
1087
1097
  end
1088
1098
 
1089
- value_type = if return_types.size == 1
1090
- return_types.first
1091
- else
1092
- AST::Builtin::Array.instance_type(union_type(*return_types))
1093
- end
1094
-
1095
- else
1096
- value_type = AST::Builtin.nil_type
1099
+ value_type = AST::Builtin::Array.instance_type(union_type(*return_types))
1097
1100
  end
1098
1101
 
1099
1102
  if method_return_type
1100
- unless method_return_type.is_a?(AST::Types::Void)
1101
- result = check_relation(sub_type: value_type, super_type: method_return_type)
1103
+ unless method_context.nil? || method_return_type.is_a?(AST::Types::Void)
1104
+ result = constr.check_relation(sub_type: value_type, super_type: method_return_type)
1102
1105
 
1103
1106
  if result.failure?
1104
1107
  typing.add_error(
1105
1108
  Diagnostic::Ruby::ReturnTypeMismatch.new(
1106
1109
  node: node,
1107
- expected: method_context&.return_type,
1110
+ expected: method_return_type,
1108
1111
  actual: value_type,
1109
1112
  result: result
1110
1113
  )
@@ -1113,14 +1116,14 @@ module Steep
1113
1116
  end
1114
1117
  end
1115
1118
 
1116
- add_typing(node, type: AST::Builtin.bottom_type)
1119
+ constr.add_typing(node, type: AST::Builtin.bottom_type)
1117
1120
  end
1118
1121
 
1119
1122
  when :break
1120
1123
  value = node.children[0]
1121
1124
 
1122
1125
  if break_context
1123
- break_type = (break_context || raise).break_type
1126
+ break_type = break_context.break_type
1124
1127
 
1125
1128
  if value
1126
1129
  check(value, break_type) do |break_type, actual_type, result|
@@ -1158,7 +1161,7 @@ module Steep
1158
1161
 
1159
1162
  if break_context
1160
1163
  if next_type = break_context.next_type
1161
- next_type = deep_expand_alias(next_type)
1164
+ next_type = deep_expand_alias(next_type) || next_type
1162
1165
 
1163
1166
  if value
1164
1167
  _, constr = check(value, next_type) do |break_type, actual_type, result|
@@ -1201,7 +1204,7 @@ module Steep
1201
1204
 
1202
1205
  when :procarg0
1203
1206
  yield_self do
1204
- constr = self
1207
+ constr = self #: TypeConstruction
1205
1208
 
1206
1209
  node.children.each do |arg|
1207
1210
  if arg.is_a?(Symbol)
@@ -1227,7 +1230,7 @@ module Steep
1227
1230
 
1228
1231
  when :mlhs
1229
1232
  yield_self do
1230
- constr = self
1233
+ constr = self #: TypeConstruction
1231
1234
 
1232
1235
  node.children.each do |arg|
1233
1236
  _, constr = constr.synthesize(arg)
@@ -1353,7 +1356,6 @@ module Steep
1353
1356
  ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
1354
1357
 
1355
1358
  if hint && check_relation(sub_type: ty, super_type: hint).success? && !hint.is_a?(AST::Types::Any) && !hint.is_a?(AST::Types::Top)
1356
-
1357
1359
  add_typing(node, type: hint)
1358
1360
  else
1359
1361
  add_typing(node, type: AST::Types::Boolean.new)
@@ -1393,8 +1395,11 @@ module Steep
1393
1395
  yield_self do
1394
1396
  constr = self
1395
1397
 
1398
+ # @type var name_node: Parser::AST::Node
1399
+ # @type var super_node: Parser::AST::Node?
1400
+
1396
1401
  name_node, super_node, _ = node.children
1397
- _, constr, class_name = synthesize_constant(name_node, name_node.children[0], name_node.children[1]) do
1402
+ _, constr, class_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
1398
1403
  typing.add_error(
1399
1404
  Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).class!
1400
1405
  )
@@ -1421,9 +1426,9 @@ module Steep
1421
1426
 
1422
1427
  with_class_constr(node, class_name, super_name) do |constructor|
1423
1428
  if module_type = constructor.module_context&.module_type
1424
- _, constructor = constructor.add_typing(name, type: module_type)
1429
+ _, constructor = constructor.add_typing(name_node, type: module_type)
1425
1430
  else
1426
- _, constructor = constructor.fallback_to_any(name)
1431
+ _, constructor = constructor.fallback_to_any(name_node)
1427
1432
  end
1428
1433
 
1429
1434
  constructor.typing.add_context_for_node(node, context: constructor.context)
@@ -1443,8 +1448,9 @@ module Steep
1443
1448
  yield_self do
1444
1449
  constr = self
1445
1450
 
1451
+ # @type var name_node: Parser::AST::Node
1446
1452
  name_node, _ = node.children
1447
- _, constr, module_name = synthesize_constant(name_node, name_node.children[0], name_node.children[1]) do
1453
+ _, constr, module_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
1448
1454
  typing.add_error Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).module!
1449
1455
  end
1450
1456
 
@@ -1454,9 +1460,9 @@ module Steep
1454
1460
 
1455
1461
  with_module_constr(node, module_name) do |constructor|
1456
1462
  if module_type = constructor.module_context&.module_type
1457
- _, constructor = constructor.add_typing(name, type: module_type)
1463
+ _, constructor = constructor.add_typing(name_node, type: module_type)
1458
1464
  else
1459
- _, constructor = constructor.fallback_to_any(name)
1465
+ _, constructor = constructor.fallback_to_any(name_node)
1460
1466
  end
1461
1467
 
1462
1468
  constructor.typing.add_context_for_node(node, context: constructor.context)
@@ -1492,9 +1498,9 @@ module Steep
1492
1498
 
1493
1499
  constructor.synthesize(node.children[1]) if node.children[1]
1494
1500
 
1495
- if constructor.module_context!.instance_definition && module_context!.module_definition
1496
- if constructor.module_context!.instance_definition.type_name == module_context!.module_definition.type_name
1497
- module_context!.defined_module_methods.merge(constructor.module_context!.defined_instance_methods)
1501
+ if constructor.module_context.instance_definition && module_context.module_definition
1502
+ if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
1503
+ module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
1498
1504
  end
1499
1505
  end
1500
1506
  end
@@ -1521,7 +1527,7 @@ module Steep
1521
1527
 
1522
1528
  when :casgn
1523
1529
  yield_self do
1524
- constant_type, constr, constant_name = synthesize_constant(nil, node.children[0], node.children[1]) do
1530
+ constant_type, constr, constant_name = synthesize_constant_decl(nil, node.children[0], node.children[1]) do
1525
1531
  typing.add_error(
1526
1532
  Diagnostic::Ruby::UnknownConstant.new(
1527
1533
  node: node,
@@ -1570,6 +1576,7 @@ module Steep
1570
1576
  # @type var errors: Array[Diagnostic::Ruby::Base]
1571
1577
  errors = []
1572
1578
  constr = type_check_args(
1579
+ nil,
1573
1580
  args,
1574
1581
  Subtyping::Constraints.new(unknowns: []),
1575
1582
  errors
@@ -1590,7 +1597,7 @@ module Steep
1590
1597
 
1591
1598
  when :zsuper
1592
1599
  yield_self do
1593
- if method_context&.method
1600
+ if method_context && method_context.method
1594
1601
  if method_context.super_method
1595
1602
  types = method_context.super_method.method_types.map {|method_type|
1596
1603
  checker.factory.method_type(method_type, method_decls: Set[]).type.return_type
@@ -1623,22 +1630,28 @@ module Steep
1623
1630
  else
1624
1631
  node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
1625
1632
 
1626
- if hint && !(tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) }).empty?
1627
- tuples.each do |tuple|
1628
- typing.new_child(node_range) do |child_typing|
1629
- if pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
1630
- return pair.with(constr: pair.constr.save_typing)
1633
+ if hint
1634
+ tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple]
1635
+ unless tuples.empty?
1636
+ tuples.each do |tuple|
1637
+ typing.new_child(node_range) do |child_typing|
1638
+ if pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
1639
+ return pair.with(constr: pair.constr.save_typing)
1640
+ end
1631
1641
  end
1632
1642
  end
1633
1643
  end
1634
1644
  end
1635
1645
 
1636
- if hint && !(arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) }).empty?
1637
- arrays.each do |array|
1638
- typing.new_child(node_range) do |child_typing|
1639
- pair = with_new_typing(child_typing).try_array_type(node, array)
1640
- if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
1641
- return pair.with(constr: pair.constr.save_typing)
1646
+ if hint
1647
+ arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) } #: Array[AST::Types::Name::Instance]
1648
+ unless arrays.empty?
1649
+ arrays.each do |array|
1650
+ typing.new_child(node_range) do |child_typing|
1651
+ pair = with_new_typing(child_typing).try_array_type(node, array)
1652
+ if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
1653
+ return pair.with(constr: pair.constr.save_typing)
1654
+ end
1642
1655
  end
1643
1656
  end
1644
1657
  end
@@ -1771,7 +1784,7 @@ module Steep
1771
1784
  end
1772
1785
 
1773
1786
  constr = constr.update_type_env do |env|
1774
- envs = []
1787
+ envs = [] #: Array[TypeInference::TypeEnv]
1775
1788
 
1776
1789
  if true_pair
1777
1790
  unless true_pair.type.is_a?(AST::Types::Bot)
@@ -1798,13 +1811,15 @@ module Steep
1798
1811
 
1799
1812
  when :case
1800
1813
  yield_self do
1814
+ # @type var node: Parser::AST::Node & Parser::AST::_CaseNode
1815
+
1801
1816
  cond, *whens, els = node.children
1802
1817
 
1803
- constr = self
1818
+ constr = self #: TypeConstruction
1804
1819
  interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
1805
1820
 
1806
1821
  if cond
1807
- branch_results = []
1822
+ branch_results = [] #: Array[Pair]
1808
1823
 
1809
1824
  cond_type, constr = constr.synthesize(cond)
1810
1825
  _, cond_vars = interpreter.decompose_value(cond)
@@ -1858,6 +1873,8 @@ module Steep
1858
1873
  end
1859
1874
 
1860
1875
  if els
1876
+ node.loc.else or raise
1877
+
1861
1878
  begin_pos = node.loc.else.end_pos
1862
1879
  end_pos = node.loc.end.begin_pos
1863
1880
  typing.add_context(begin_pos..end_pos, context: when_constr.context)
@@ -1885,19 +1902,21 @@ module Steep
1885
1902
  end
1886
1903
  end
1887
1904
  else
1888
- branch_results = []
1905
+ branch_results = [] #: Array[Pair]
1889
1906
 
1890
1907
  condition_constr = constr
1891
1908
  clause_constr = constr
1892
1909
 
1893
1910
  whens.each do |when_clause|
1894
1911
  when_clause_constr = condition_constr
1895
- body_envs = []
1912
+ body_envs = [] #: Array[TypeInference::TypeEnv]
1896
1913
 
1914
+ # @type var tests: Array[Parser::AST::Node]
1915
+ # @type var body: Parser::AST::Node?
1897
1916
  *tests, body = when_clause.children
1898
1917
 
1899
1918
  tests.each do |test|
1900
- test_type, condition_constr = condition_constr.synthesize(test, condition: true).to_ary
1919
+ test_type, condition_constr = condition_constr.synthesize(test, condition: true)
1901
1920
  truthy_env, falsy_env = interpreter.eval(env: condition_constr.context.type_env, node: test)
1902
1921
 
1903
1922
  condition_constr = condition_constr.update_type_env { falsy_env }
@@ -1975,7 +1994,7 @@ module Steep
1975
1994
  end
1976
1995
 
1977
1996
  resbody_construction = body_constr.for_branch(resbody).update_type_env do |env|
1978
- assignments = {}
1997
+ assignments = {} #: Hash[Symbol, AST::Types::t]
1979
1998
 
1980
1999
  case
1981
2000
  when exn_classes && var_name && exn_types
@@ -2025,8 +2044,12 @@ module Steep
2025
2044
  klasses, asgn, body = node.children
2026
2045
  synthesize(klasses) if klasses
2027
2046
  synthesize(asgn) if asgn
2028
- body_type = synthesize(body, hint: hint).type if body
2029
- add_typing(node, type: body_type)
2047
+ if body
2048
+ body_type = synthesize(body, hint: hint).type
2049
+ add_typing(node, type: body_type)
2050
+ else
2051
+ add_typing(node, type: AST::Builtin.nil_type)
2052
+ end
2030
2053
  end
2031
2054
 
2032
2055
  when :ensure
@@ -2034,7 +2057,11 @@ module Steep
2034
2057
  body, ensure_body = node.children
2035
2058
  body_type = synthesize(body).type if body
2036
2059
  synthesize(ensure_body) if ensure_body
2037
- add_typing(node, type: union_type(body_type))
2060
+ if body_type
2061
+ add_typing(node, type: body_type)
2062
+ else
2063
+ add_typing(node, type: AST::Builtin.nil_type)
2064
+ end
2038
2065
  end
2039
2066
 
2040
2067
  when :masgn
@@ -2054,13 +2081,13 @@ module Steep
2054
2081
  if method_type = (each.method_types || []).find {|type| type.block && type.block.type.params.first_param }
2055
2082
  if block = method_type.block
2056
2083
  if first_param = block.type.params.first_param
2057
- var_type = first_param.type
2084
+ var_type = first_param.type #: AST::Types::t
2058
2085
  end
2059
2086
  end
2060
2087
  end
2061
2088
  end
2062
2089
  end
2063
- var_name = asgn.children[0]
2090
+ var_name = asgn.children[0] #: Symbol
2064
2091
 
2065
2092
  if var_type
2066
2093
  if body
@@ -2106,8 +2133,14 @@ module Steep
2106
2133
  body_env, exit_env = truthy_env, falsy_env
2107
2134
  when :until
2108
2135
  exit_env, body_env = truthy_env, falsy_env
2136
+ else
2137
+ raise
2109
2138
  end
2110
2139
 
2140
+ body_env or raise
2141
+ exit_env or raise
2142
+
2143
+
2111
2144
  if body
2112
2145
  pins = body_env.pin_local_variables(nil)
2113
2146
  body_env = body_env.merge(local_variable_types: pins)
@@ -2131,7 +2164,7 @@ module Steep
2131
2164
  yield_self do
2132
2165
  cond, body = node.children
2133
2166
 
2134
- _, cond_constr, = synthesize(cond).to_ary
2167
+ _, cond_constr, = synthesize(cond)
2135
2168
 
2136
2169
  if body
2137
2170
  for_loop =
@@ -2146,7 +2179,7 @@ module Steep
2146
2179
 
2147
2180
  add_typing(node, type: AST::Builtin.nil_type, constr: constr)
2148
2181
  else
2149
- add_typing(node, type: AST::Builtin.nil_type, constr: cond_pair.constr)
2182
+ add_typing(node, type: AST::Builtin.nil_type, constr: cond_constr)
2150
2183
  end
2151
2184
  end
2152
2185
 
@@ -2155,12 +2188,12 @@ module Steep
2155
2188
 
2156
2189
  constr = self
2157
2190
  begin_type, constr = if begin_node
2158
- constr.synthesize(begin_node)
2191
+ constr.synthesize(begin_node).to_ary
2159
2192
  else
2160
2193
  [AST::Builtin.nil_type, constr]
2161
2194
  end
2162
2195
  end_type, constr = if end_node
2163
- constr.synthesize(end_node)
2196
+ constr.synthesize(end_node).to_ary
2164
2197
  else
2165
2198
  [AST::Builtin.nil_type, constr]
2166
2199
  end
@@ -2298,14 +2331,18 @@ module Steep
2298
2331
  Steep.logger.error "Passing multiple args through Symbol#to_proc is not supported yet"
2299
2332
  end
2300
2333
  when value == nil
2301
- type = AST::Types::Proc.new(
2302
- type: method_context.method_type.block.type,
2303
- location: nil,
2304
- block: nil,
2305
- self_type: method_context.method_type.block.self_type
2306
- )
2307
- if method_context.method_type.block.optional?
2308
- type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
2334
+ if block_type = method_context!.block_type
2335
+ type = AST::Types::Proc.new(
2336
+ type: block_type.type,
2337
+ location: nil,
2338
+ block: nil,
2339
+ self_type: block_type.self_type
2340
+ )
2341
+ if block_type.optional?
2342
+ type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
2343
+ end
2344
+ else
2345
+ type = AST::Builtin.nil_type
2309
2346
  end
2310
2347
  end
2311
2348
 
@@ -2328,9 +2365,12 @@ module Steep
2328
2365
 
2329
2366
  type, constr = synthesize(rhs, hint: hint)
2330
2367
 
2331
- var_type = if module_context&.class_variables
2332
- module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
2333
- end
2368
+ var_type =
2369
+ if class_vars = module_context.class_variables
2370
+ if ty = class_vars[name]
2371
+ checker.factory.type(ty)
2372
+ end
2373
+ end
2334
2374
 
2335
2375
  if var_type
2336
2376
  result = constr.check_relation(sub_type: type, super_type: var_type)
@@ -2352,10 +2392,13 @@ module Steep
2352
2392
  end
2353
2393
 
2354
2394
  when :cvar
2355
- name = node.children[0]
2356
- var_type = if module_context&.class_variables
2357
- module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
2358
- end
2395
+ name = node.children[0] #: Symbol
2396
+ var_type =
2397
+ if cvs = module_context.class_variables
2398
+ if ty = cvs[name]
2399
+ checker.factory.type(ty)
2400
+ end
2401
+ end
2359
2402
 
2360
2403
  if var_type
2361
2404
  add_typing node, type: var_type
@@ -2383,7 +2426,7 @@ module Steep
2383
2426
  end
2384
2427
 
2385
2428
  when :args
2386
- constr = self
2429
+ constr = self #: TypeConstruction
2387
2430
 
2388
2431
  each_child_node(node) do |child|
2389
2432
  _, constr = constr.synthesize(child)
@@ -2396,7 +2439,7 @@ module Steep
2396
2439
  # @type var as_type: AST::Node::TypeAssertion
2397
2440
  asserted_node, as_type = node.children
2398
2441
 
2399
- if type = as_type.type?(module_context!.nesting, checker.factory, [])
2442
+ if type = as_type.type?(module_context.nesting, checker.factory, [])
2400
2443
  actual_type, constr = synthesize(asserted_node, hint: type)
2401
2444
 
2402
2445
  if no_subtyping?(sub_type: type, super_type: actual_type) && no_subtyping?(sub_type: actual_type, super_type: type)
@@ -2426,6 +2469,9 @@ module Steep
2426
2469
  constr.add_typing(node, type: type)
2427
2470
  end
2428
2471
 
2472
+ when :forwarded_args, :forward_arg
2473
+ add_typing(node, type: AST::Builtin.any_type)
2474
+
2429
2475
  else
2430
2476
  typing.add_error(Diagnostic::Ruby::UnsupportedSyntax.new(node: node))
2431
2477
  add_typing(node, type: AST::Builtin.any_type)
@@ -2439,7 +2485,7 @@ module Steep
2439
2485
  end
2440
2486
  rescue RBS::BaseError => exn
2441
2487
  Steep.logger.warn { "Unexpected RBS error: #{exn.message}" }
2442
- exn.backtrace.each {|loc| Steep.logger.warn " #{loc}" }
2488
+ exn.backtrace&.each {|loc| Steep.logger.warn " #{loc}" }
2443
2489
  typing.add_error(Diagnostic::Ruby::UnexpectedError.new(node: node, error: exn))
2444
2490
  type_any_rec(node)
2445
2491
  rescue StandardError => exn
@@ -2466,7 +2512,7 @@ module Steep
2466
2512
  when :send
2467
2513
  yield_self do
2468
2514
  if self_class?(node)
2469
- module_type = expand_alias(module_context!.module_type)
2515
+ module_type = expand_alias(module_context.module_type)
2470
2516
  type = if module_type.is_a?(AST::Types::Name::Singleton)
2471
2517
  AST::Types::Name::Singleton.new(name: module_type.name)
2472
2518
  else
@@ -2482,7 +2528,7 @@ module Steep
2482
2528
  yield_self do
2483
2529
  send_type, constr =
2484
2530
  if self_class?(node)
2485
- module_type = expand_alias(module_context!.module_type)
2531
+ module_type = expand_alias(module_context.module_type)
2486
2532
  type = if module_type.is_a?(AST::Types::Name::Singleton)
2487
2533
  AST::Types::Name::Singleton.new(name: module_type.name)
2488
2534
  else
@@ -2501,6 +2547,7 @@ module Steep
2501
2547
  yield_self do
2502
2548
  send_node, params, body = node.children
2503
2549
  if send_node.type == :lambda
2550
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
2504
2551
  type_lambda(node, params_node: params, body_node: body, type_hint: hint)
2505
2552
  else
2506
2553
  type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
@@ -2519,6 +2566,7 @@ module Steep
2519
2566
  params = Parser::AST::Node.new(:args, arg_nodes)
2520
2567
 
2521
2568
  if send_node.type == :lambda
2569
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
2522
2570
  type_lambda(node, params_node: params, body_node: body, type_hint: hint)
2523
2571
  else
2524
2572
  type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
@@ -2632,7 +2680,7 @@ module Steep
2632
2680
  hint = masgn.hint_for_mlhs(lhs, context.type_env)
2633
2681
 
2634
2682
  rhs_type, lhs_constr = try_tuple_type!(rhs, hint: hint).to_ary
2635
- rhs_type = deep_expand_alias(rhs_type)
2683
+ rhs_type = deep_expand_alias(rhs_type) || rhs_type
2636
2684
 
2637
2685
  falsys, truthys = partition_flatten_types(rhs_type) do |type|
2638
2686
  type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
@@ -2680,6 +2728,57 @@ module Steep
2680
2728
  constr.add_typing(node, type: truthy_rhs_type)
2681
2729
  end
2682
2730
 
2731
+ def synthesize_constant_decl(node, parent_node, constant_name, &block)
2732
+ const_name = module_name_from_node(parent_node, constant_name)
2733
+
2734
+ if const_name && type = context.type_env.annotated_constant(const_name)
2735
+ # const-type annotation wins
2736
+ if node
2737
+ constr = synthesize_children(node)
2738
+ type, constr = constr.add_typing(node, type: type)
2739
+ [type, constr, nil]
2740
+ else
2741
+ [type, self, nil]
2742
+ end
2743
+ else
2744
+ if parent_node
2745
+ synthesize_constant(node, parent_node, constant_name, &block)
2746
+ else
2747
+ if nesting
2748
+ if parent_nesting = nesting[1]
2749
+ if constant = context.type_env.constant_env.resolver.table.children(parent_nesting)&.fetch(constant_name, nil)
2750
+ return [checker.factory.type(constant.type), self, constant.name]
2751
+ end
2752
+ end
2753
+
2754
+ if block_given?
2755
+ yield
2756
+ else
2757
+ if node
2758
+ typing.add_error(
2759
+ Diagnostic::Ruby::UnknownConstant.new(node: node, name: constant_name)
2760
+ )
2761
+ end
2762
+ end
2763
+
2764
+ constr = self #: TypeConstruction
2765
+ if node
2766
+ _, constr = add_typing(node, type: AST::Builtin.any_type)
2767
+ end
2768
+
2769
+ [
2770
+ AST::Builtin.any_type,
2771
+ constr,
2772
+ nil
2773
+ ]
2774
+ else
2775
+ # No neesting
2776
+ synthesize_constant(node, nil, constant_name, &block)
2777
+ end
2778
+ end
2779
+ end
2780
+ end
2781
+
2683
2782
  def synthesize_constant(node, parent_node, constant_name)
2684
2783
  const_name = module_name_from_node(parent_node, constant_name)
2685
2784
 
@@ -2795,7 +2894,7 @@ module Steep
2795
2894
 
2796
2895
  block_constr.typing.add_context_for_body(node, context: block_constr.context)
2797
2896
 
2798
- params.params.each do |param|
2897
+ params.each_single_param do |param|
2799
2898
  _, block_constr = block_constr.synthesize(param.node, hint: param.type)
2800
2899
  end
2801
2900
 
@@ -2843,8 +2942,13 @@ module Steep
2843
2942
  Interface::Substitution.build([], [], self_type: block_constr.self_type)
2844
2943
  )
2845
2944
 
2846
- if expected_block_type = block_constr.block_context.body_type
2847
- type_vars = expected_block_type.free_variables
2945
+ if expected_block_type = block_constr.block_context!.body_type
2946
+ type_vars = expected_block_type.free_variables.filter_map do |var|
2947
+ case var
2948
+ when Symbol
2949
+ var
2950
+ end
2951
+ end
2848
2952
  subst = Interface::Substitution.build(type_vars, type_vars.map { AST::Builtin.any_type })
2849
2953
  expected_block_type = expected_block_type.subst(subst)
2850
2954
 
@@ -2879,7 +2983,7 @@ module Steep
2879
2983
  end
2880
2984
 
2881
2985
  def synthesize_children(node, skips: [])
2882
- skips = Set.new.compare_by_identity.merge(skips)
2986
+ skips = Set.new.compare_by_identity.merge(skips).delete(nil)
2883
2987
 
2884
2988
  # @type var constr: TypeConstruction
2885
2989
  constr = self
@@ -2902,8 +3006,11 @@ module Steep
2902
3006
  return false unless call.node.type == :send || call.node.type == :csend
2903
3007
  return false unless call.pure? || KNOWN_PURE_METHODS.superset?(Set.new(call.method_decls.map(&:method_name)))
2904
3008
 
2905
- [receiver, *arguments].all? do |node|
2906
- !node || value_node?(node) || context.type_env[node]
3009
+ argishes = [*arguments]
3010
+ argishes << receiver if receiver
3011
+
3012
+ argishes.all? do |node|
3013
+ value_node?(node) || context.type_env[node]
2907
3014
  end
2908
3015
  end
2909
3016
 
@@ -2944,7 +3051,11 @@ module Steep
2944
3051
  end
2945
3052
  else
2946
3053
  constr = constr.update_type_env do |env|
2947
- env.invalidate_pure_node(receiver)
3054
+ if receiver
3055
+ env.invalidate_pure_node(receiver)
3056
+ else
3057
+ env
3058
+ end
2948
3059
  end
2949
3060
  end
2950
3061
  end
@@ -2955,13 +3066,14 @@ module Steep
2955
3066
  call = call.with_return_type(optional_type)
2956
3067
  end
2957
3068
  else
2958
- errors = []
3069
+ errors = [] #: Array[Diagnostic::Ruby::Base]
2959
3070
 
2960
3071
  skips = [receiver]
2961
3072
  skips << node.children[0] if node.type == :block
2962
3073
 
2963
3074
  constr = synthesize_children(node, skips: skips)
2964
3075
  if block_params
3076
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
2965
3077
  block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
2966
3078
 
2967
3079
  constr.type_block_without_hint(
@@ -2982,7 +3094,7 @@ module Steep
2982
3094
  )
2983
3095
  call = TypeInference::MethodCall::Error.new(
2984
3096
  node: node,
2985
- context: context.method_context,
3097
+ context: context.call_context,
2986
3098
  method_name: method_name,
2987
3099
  receiver_type: receiver_type,
2988
3100
  errors: errors
@@ -2991,7 +3103,7 @@ module Steep
2991
3103
 
2992
3104
  constr.add_call(call)
2993
3105
  else
2994
- skips = []
3106
+ skips = [] #: Array[Parser::AST::Node?]
2995
3107
  skips << receiver if receiver
2996
3108
  skips << node.children[0] if node.type == :block
2997
3109
  skips << block_params if block_params
@@ -2999,6 +3111,7 @@ module Steep
2999
3111
 
3000
3112
  constr = synthesize_children(node, skips: skips)
3001
3113
  if block_params
3114
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
3002
3115
  block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3003
3116
 
3004
3117
  constr.type_block_without_hint(
@@ -3023,7 +3136,7 @@ module Steep
3023
3136
  constr.add_call(
3024
3137
  TypeInference::MethodCall::NoMethodError.new(
3025
3138
  node: node,
3026
- context: context.method_context,
3139
+ context: context.call_context,
3027
3140
  method_name: method_name,
3028
3141
  receiver_type: receiver_type,
3029
3142
  error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: interface&.type || receiver_type)
@@ -3070,46 +3183,65 @@ module Steep
3070
3183
  receiver_type = checker.factory.deep_expand_alias(recv_type)
3071
3184
  private = receiver.nil? || receiver.type == :self
3072
3185
 
3073
- type, constr = case receiver_type
3074
- when nil
3075
- raise
3076
-
3077
- when AST::Types::Any
3078
- constr = constr.synthesize_children(node, skips: [receiver])
3079
- constr.add_call(
3080
- TypeInference::MethodCall::Untyped.new(
3081
- node: node,
3082
- context: context.method_context,
3083
- method_name: method_name
3084
- )
3085
- )
3186
+ type, constr =
3187
+ case receiver_type
3188
+ when nil
3189
+ raise
3086
3190
 
3087
- else
3088
- if interface = calculate_interface(receiver_type, private: private)
3089
- constr.type_send_interface(
3090
- node,
3091
- interface: interface,
3092
- receiver: receiver,
3093
- receiver_type: receiver_type,
3094
- method_name: method_name,
3095
- arguments: arguments,
3096
- block_params: block_params,
3097
- block_body: block_body,
3098
- tapp: tapp
3099
- )
3100
- else
3101
- constr = constr.synthesize_children(node, skips: [receiver])
3102
- constr.add_call(
3103
- TypeInference::MethodCall::NoMethodError.new(
3104
- node: node,
3105
- context: context.method_context,
3106
- method_name: method_name,
3107
- receiver_type: receiver_type,
3108
- error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
3109
- )
3110
- )
3111
- end
3112
- end
3191
+ when AST::Types::Any
3192
+ case node.type
3193
+ when :block, :numblock
3194
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
3195
+ block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3196
+ block_params or raise
3197
+
3198
+ constr = constr.synthesize_children(node.children[0])
3199
+
3200
+ constr.type_block_without_hint(
3201
+ node: node,
3202
+ block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
3203
+ block_annotations: block_annotations,
3204
+ block_body: block_body
3205
+ ) do |error|
3206
+ constr.typing.errors << error
3207
+ end
3208
+ else
3209
+ constr = constr.synthesize_children(node, skips: [receiver])
3210
+ end
3211
+
3212
+ constr.add_call(
3213
+ TypeInference::MethodCall::Untyped.new(
3214
+ node: node,
3215
+ context: context.call_context,
3216
+ method_name: method_name
3217
+ )
3218
+ )
3219
+ else
3220
+ if interface = calculate_interface(receiver_type, private: private)
3221
+ constr.type_send_interface(
3222
+ node,
3223
+ interface: interface,
3224
+ receiver: receiver,
3225
+ receiver_type: receiver_type,
3226
+ method_name: method_name,
3227
+ arguments: arguments,
3228
+ block_params: block_params,
3229
+ block_body: block_body,
3230
+ tapp: tapp
3231
+ )
3232
+ else
3233
+ constr = constr.synthesize_children(node, skips: [receiver])
3234
+ constr.add_call(
3235
+ TypeInference::MethodCall::NoMethodError.new(
3236
+ node: node,
3237
+ context: context.call_context,
3238
+ method_name: method_name,
3239
+ receiver_type: receiver_type,
3240
+ error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
3241
+ )
3242
+ )
3243
+ end
3244
+ end
3113
3245
 
3114
3246
  Pair.new(type: type, constr: constr)
3115
3247
  end
@@ -3117,8 +3249,8 @@ module Steep
3117
3249
  def builder_config
3118
3250
  Interface::Builder::Config.new(
3119
3251
  self_type: self_type,
3120
- class_type: module_context!.module_type,
3121
- instance_type: module_context!.instance_type,
3252
+ class_type: module_context.module_type,
3253
+ instance_type: module_context.instance_type,
3122
3254
  variable_bounds: variable_context.upper_bounds
3123
3255
  )
3124
3256
  end
@@ -3173,7 +3305,7 @@ module Steep
3173
3305
  _, constr = add_typing(node, type: type)
3174
3306
  call = TypeInference::MethodCall::Special.new(
3175
3307
  node: node,
3176
- context: constr.context.method_context,
3308
+ context: constr.context.call_context,
3177
3309
  method_name: decl.method_name.method_name,
3178
3310
  receiver_type: receiver_type,
3179
3311
  actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
@@ -3197,7 +3329,7 @@ module Steep
3197
3329
  _, constr = add_typing(node, type: type)
3198
3330
  call = TypeInference::MethodCall::Special.new(
3199
3331
  node: node,
3200
- context: constr.context.method_context,
3332
+ context: constr.context.call_context,
3201
3333
  method_name: decl.method_name.method_name,
3202
3334
  receiver_type: receiver_type,
3203
3335
  actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
@@ -3214,7 +3346,7 @@ module Steep
3214
3346
  end
3215
3347
 
3216
3348
  def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:)
3217
- node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
3349
+ node_range = node.loc.expression.to_range
3218
3350
 
3219
3351
  # @type var fails: Array[[TypeInference::MethodCall::t, TypeConstruction]]
3220
3352
  fails = []
@@ -3327,11 +3459,11 @@ module Steep
3327
3459
  end
3328
3460
  end
3329
3461
 
3330
- def type_check_args(args, constraints, errors)
3462
+ def type_check_args(method_name, args, constraints, errors)
3331
3463
  # @type var constr: TypeConstruction
3332
3464
  constr = self
3333
3465
 
3334
- es = args.each do |arg|
3466
+ forwarded_args, es = args.each do |arg|
3335
3467
  case arg
3336
3468
  when TypeInference::SendArgs::PositionalArgs::NodeParamPair
3337
3469
  _, constr = constr.type_check_argument(
@@ -3404,20 +3536,48 @@ module Steep
3404
3536
 
3405
3537
  when TypeInference::SendArgs::KeywordArgs::MissingKeyword
3406
3538
  # ignore
3539
+
3407
3540
  else
3408
- raise arg.inspect
3541
+ raise (_ = arg).inspect
3409
3542
  end
3410
3543
  end
3411
3544
 
3412
3545
  errors.push(*es)
3413
3546
 
3547
+ if forwarded_args
3548
+ method_name or raise "method_name cannot be nil if `forwarded_args` is given, because proc/block doesn't support `...` arg"
3549
+
3550
+ (params, block = context.method_context&.forward_arg_type) or raise
3551
+
3552
+ checker.with_context(self_type: self_type, instance_type: context.module_context.instance_type, class_type: context.module_context.module_type, constraints: constraints) do
3553
+ result = checker.check_method_params(
3554
+ :"... (argument forwarding)",
3555
+ Subtyping::Relation.new(
3556
+ sub_type: forwarded_args.params,
3557
+ super_type: params
3558
+ )
3559
+ )
3560
+
3561
+ if result.failure?
3562
+ errors.push(
3563
+ Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
3564
+ method_name: method_name,
3565
+ node: forwarded_args.node,
3566
+ params_pair: [params, forwarded_args.params],
3567
+ result: result
3568
+ )
3569
+ )
3570
+ end
3571
+ end
3572
+ end
3573
+
3414
3574
  constr
3415
3575
  end
3416
3576
 
3417
3577
  def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, tapp:)
3418
3578
  constr = self
3419
3579
 
3420
- if tapp && type_args = tapp.types?(module_context!.nesting, checker.factory, [])
3580
+ if tapp && type_args = tapp.types?(module_context.nesting, checker.factory, [])
3421
3581
  type_arity = method_type.type_params.size
3422
3582
  type_param_names = method_type.type_params.map(&:name)
3423
3583
 
@@ -3477,7 +3637,7 @@ module Steep
3477
3637
  )
3478
3638
  end
3479
3639
 
3480
- type_params = []
3640
+ type_params = [] #: Array[Interface::TypeParam]
3481
3641
  type_param_names.clear
3482
3642
  else
3483
3643
  # Infer type application
@@ -3499,12 +3659,12 @@ module Steep
3499
3659
  constraints = Subtyping::Constraints.new(unknowns: type_params.map(&:name))
3500
3660
  ccontext = Subtyping::Constraints::Context.new(
3501
3661
  self_type: self_type,
3502
- instance_type: module_context!.instance_type,
3503
- class_type: module_context!.module_type,
3662
+ instance_type: module_context.instance_type,
3663
+ class_type: module_context.module_type,
3504
3664
  variance: variance
3505
3665
  )
3506
3666
 
3507
- upper_bounds = {}
3667
+ upper_bounds = {} #: Hash[Symbol, AST::Types::t]
3508
3668
 
3509
3669
  type_params.each do |param|
3510
3670
  if ub = param.upper_bound
@@ -3514,11 +3674,14 @@ module Steep
3514
3674
  end
3515
3675
 
3516
3676
  checker.push_variable_bounds(upper_bounds) do
3677
+ # @type block: [TypeInference::MethodCall::t, TypeConstruction]
3678
+
3517
3679
  # @type var errors: Array[Diagnostic::Ruby::Base]
3518
3680
  errors = []
3519
3681
 
3520
3682
  args = TypeInference::SendArgs.new(node: node, arguments: arguments, type: method_type)
3521
3683
  constr = constr.type_check_args(
3684
+ method_name,
3522
3685
  args,
3523
3686
  constraints,
3524
3687
  errors
@@ -3526,6 +3689,8 @@ module Steep
3526
3689
 
3527
3690
  if block_params
3528
3691
  # block is given
3692
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
3693
+
3529
3694
  block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3530
3695
  block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
3531
3696
 
@@ -3596,12 +3761,14 @@ module Steep
3596
3761
  )
3597
3762
  }
3598
3763
 
3764
+ method_type.block or raise
3765
+
3599
3766
  if solved
3600
3767
  # Ready for type check the body of the block
3601
3768
  block_constr = block_constr.update_type_env {|env| env.subst(s) }
3602
3769
  block_constr = block_constr.update_context {|context|
3603
3770
  context.with(
3604
- self_type: method_type.block&.self_type || context.self_type,
3771
+ self_type: method_type.block.self_type || context.self_type,
3605
3772
  type_env: context.type_env.subst(s),
3606
3773
  block_context: context.block_context&.subst(s),
3607
3774
  break_context: context.break_context&.subst(s)
@@ -3708,6 +3875,21 @@ module Steep
3708
3875
  arg = args.block_pass_arg
3709
3876
 
3710
3877
  case
3878
+ when forwarded_args_node = args.forwarded_args_node
3879
+ (_, block = method_context!.forward_arg_type) or raise
3880
+
3881
+ method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
3882
+ forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
3883
+
3884
+ if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
3885
+ errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
3886
+ method_name: method_name,
3887
+ node: forwarded_args_node,
3888
+ block_pair: [block, method_type.block],
3889
+ result: result
3890
+ )
3891
+ end
3892
+
3711
3893
  when arg.compatible?
3712
3894
  if arg.node
3713
3895
  # Block pass (&block) is given
@@ -3770,7 +3952,10 @@ module Steep
3770
3952
  )
3771
3953
 
3772
3954
  when arg.unexpected_block?
3773
- # Unexpected block is given
3955
+ # Unexpected block pass node is given
3956
+
3957
+ arg.node or raise
3958
+
3774
3959
  method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
3775
3960
  constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
3776
3961
  }
@@ -3791,7 +3976,7 @@ module Steep
3791
3976
  call = if errors.empty?
3792
3977
  TypeInference::MethodCall::Typed.new(
3793
3978
  node: node,
3794
- context: context.method_context,
3979
+ context: context.call_context,
3795
3980
  receiver_type: receiver_type,
3796
3981
  method_name: method_name,
3797
3982
  actual_method_type: method_type,
@@ -3801,7 +3986,7 @@ module Steep
3801
3986
  else
3802
3987
  TypeInference::MethodCall::Error.new(
3803
3988
  node: node,
3804
- context: context.method_context,
3989
+ context: context.call_context,
3805
3990
  receiver_type: receiver_type,
3806
3991
  method_name: method_name,
3807
3992
  return_type: return_type || method_type.type.return_type,
@@ -3871,7 +4056,7 @@ module Steep
3871
4056
 
3872
4057
  block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
3873
4058
 
3874
- if expected_block_type = block_constr.block_context.body_type
4059
+ if expected_block_type = block_constr.block_context!.body_type
3875
4060
  block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
3876
4061
  Diagnostic::Ruby::BlockBodyTypeMismatch.new(
3877
4062
  node: node,
@@ -3947,8 +4132,7 @@ module Steep
3947
4132
 
3948
4133
  param_types_hash.delete_if {|name, _| SPECIAL_LVAR_NAMES.include?(name) }
3949
4134
 
3950
- param_types = param_types_hash.each.with_object({}) do |pair, hash|
3951
- # @type var hash: Hash[Symbol, [AST::Types::t, AST::Types::t?]]
4135
+ param_types = param_types_hash.each.with_object({}) do |pair, hash| #$ Hash[Symbol, [AST::Types::t, AST::Types::t?]]
3952
4136
  name, type = pair
3953
4137
  hash[name] = [type, nil]
3954
4138
  end
@@ -4034,7 +4218,7 @@ module Steep
4034
4218
 
4035
4219
  def synthesize_block(node:, block_type_hint:, block_body:)
4036
4220
  if block_body
4037
- body_type, _, context = synthesize(block_body, hint: block_context.body_type || block_type_hint)
4221
+ body_type, _, context = synthesize(block_body, hint: block_context&.body_type || block_type_hint)
4038
4222
 
4039
4223
  range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
4040
4224
  typing.add_context(range, context: context)
@@ -4055,7 +4239,7 @@ module Steep
4055
4239
 
4056
4240
  def union_type(*types)
4057
4241
  raise if types.empty?
4058
- AST::Types::Union.build(types: types)
4242
+ AST::Types::Union.build(types: types.compact)
4059
4243
  end
4060
4244
 
4061
4245
  def union_type_unify(*types)
@@ -4104,14 +4288,18 @@ module Steep
4104
4288
  return unless member_decl_count == 1
4105
4289
 
4106
4290
  expected_instance_method_names = (module_context.instance_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
4107
- if method.implemented_in == module_context.instance_definition.type_name
4108
- set << name
4291
+ if method.implemented_in
4292
+ if method.implemented_in == module_context.instance_definition&.type_name
4293
+ set << name
4294
+ end
4109
4295
  end
4110
4296
  end
4111
4297
  expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
4112
4298
  if name != :new
4113
- if method.implemented_in == module_context.module_definition.type_name
4114
- set << name
4299
+ if method.implemented_in
4300
+ if method.implemented_in == module_context.module_definition&.type_name
4301
+ set << name
4302
+ end
4115
4303
  end
4116
4304
  end
4117
4305
  end
@@ -4188,18 +4376,20 @@ module Steep
4188
4376
  end
4189
4377
 
4190
4378
  def namespace_module?(node)
4191
- nodes = case node.type
4192
- when :class, :module
4193
- node.children.last&.yield_self {|child|
4194
- if child.type == :begin
4195
- child.children
4196
- else
4197
- [child]
4198
- end
4199
- } || []
4200
- else
4201
- return false
4202
- end
4379
+ # @type var nodes: Array[Parser::AST::Node]
4380
+ nodes =
4381
+ case node.type
4382
+ when :class, :module
4383
+ node.children.last&.yield_self {|child|
4384
+ if child.type == :begin
4385
+ child.children
4386
+ else
4387
+ [child]
4388
+ end
4389
+ } || []
4390
+ else
4391
+ return false
4392
+ end
4203
4393
 
4204
4394
  !nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
4205
4395
  end
@@ -4228,18 +4418,19 @@ module Steep
4228
4418
  end
4229
4419
 
4230
4420
  def select_flatten_types(type, &block)
4231
- types = flatten_union(deep_expand_alias(type))
4421
+ types = flatten_union(deep_expand_alias(type) || type)
4232
4422
  types.select(&block)
4233
4423
  end
4234
4424
 
4235
4425
  def partition_flatten_types(type, &block)
4236
- types = flatten_union(deep_expand_alias(type))
4426
+ types = flatten_union(deep_expand_alias(type) || type)
4237
4427
  types.partition(&block)
4238
4428
  end
4239
4429
 
4240
4430
  def flatten_array_elements(type)
4241
- flatten_union(deep_expand_alias(type)).flat_map do |type|
4431
+ flatten_union(deep_expand_alias(type) || type).flat_map do |type|
4242
4432
  if AST::Builtin::Array.instance_type?(type)
4433
+ # @type var type: AST::Types::Name::Instance
4243
4434
  type.args
4244
4435
  else
4245
4436
  [type]
@@ -4248,7 +4439,12 @@ module Steep
4248
4439
  end
4249
4440
 
4250
4441
  def expand_alias(type, &block)
4251
- checker.factory.expand_alias(type, &block)
4442
+ typ = checker.factory.expand_alias(type)
4443
+ if block
4444
+ yield(typ)
4445
+ else
4446
+ typ
4447
+ end
4252
4448
  end
4253
4449
 
4254
4450
  def test_literal_type(literal, hint)
@@ -4296,9 +4492,8 @@ module Steep
4296
4492
  def try_tuple_type(array_node, hint)
4297
4493
  raise unless array_node.type == :array
4298
4494
 
4299
- constr = self
4300
- # @type var element_types: Array[AST::Types::t]
4301
- element_types = []
4495
+ constr = self #: TypeConstruction
4496
+ element_types = [] #: Array[AST::Types::t]
4302
4497
 
4303
4498
  array_node.children.each_with_index do |child, index|
4304
4499
  return if child.type == :splat
@@ -4380,11 +4575,14 @@ module Steep
4380
4575
  instance_type: module_context.instance_type,
4381
4576
  class_type: module_context.module_type
4382
4577
  )
4383
- subst = constraints.solution(
4384
- checker,
4385
- variables: type.free_variables + [var.name],
4386
- context: context
4387
- )
4578
+
4579
+ variables = (type.free_variables + [var.name]).filter_map do |name|
4580
+ case name
4581
+ when Symbol
4582
+ name
4583
+ end
4584
+ end
4585
+ subst = constraints.solution(checker, variables: variables, context: context)
4388
4586
 
4389
4587
  type.subst(subst)
4390
4588
  end
@@ -4393,8 +4591,8 @@ module Steep
4393
4591
  def try_array_type(node, hint)
4394
4592
  element_hint = hint ? hint.args[0] : nil
4395
4593
 
4396
- constr = self
4397
- element_types = []
4594
+ constr = self #: TypeConstruction
4595
+ element_types = [] #: Array[AST::Types::t]
4398
4596
 
4399
4597
  each_child_node(node) do |child|
4400
4598
  case child.type
@@ -4425,24 +4623,24 @@ module Steep
4425
4623
  def type_hash_record(hash_node, record_type)
4426
4624
  raise unless hash_node.type == :hash || hash_node.type == :kwargs
4427
4625
 
4428
- constr = self
4626
+ constr = self #: TypeConstruction
4429
4627
 
4430
4628
  if record_type
4431
4629
  hints = record_type.elements.dup
4432
4630
  else
4433
- hints = {}
4631
+ hints = {} #: Hash[AST::Types::Record::key, AST::Types::t]
4434
4632
  end
4435
4633
 
4436
- elems = {}
4634
+ elems = {} #: Hash[AST::Types::Record::key, AST::Types::t]
4437
4635
 
4438
4636
  each_child_node(hash_node) do |child|
4439
4637
  if child.type == :pair
4440
4638
  case child.children[0].type
4441
4639
  when :sym, :str, :int
4442
- key_node = child.children[0]
4443
- value_node = child.children[1]
4640
+ key_node = child.children[0] #: Parser::AST::Node
4641
+ value_node = child.children[1] #: Parser::AST::Node
4444
4642
 
4445
- key = key_node.children[0]
4643
+ key = key_node.children[0] #: String | Symbol | Integer
4446
4644
 
4447
4645
  _, constr = constr.synthesize(key_node, hint: AST::Types::Literal.new(value: key))
4448
4646
 
@@ -4471,14 +4669,10 @@ module Steep
4471
4669
  constr.add_typing(hash_node, type: type)
4472
4670
  end
4473
4671
 
4474
- # Give hash_node a type based on hint.
4475
- #
4476
- # * When hint is Record type, it may have record type.
4477
- # * When hint is union type, it tries recursively with the union cases.
4478
- # * Otherwise, it tries to be a hash instance.
4479
- #
4480
4672
  def type_hash(hash_node, hint:)
4481
- hint = deep_expand_alias(hint)
4673
+ if hint
4674
+ hint = deep_expand_alias(hint)
4675
+ end
4482
4676
  range = hash_node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
4483
4677
 
4484
4678
  case hint
@@ -4499,10 +4693,11 @@ module Steep
4499
4693
  end
4500
4694
  end
4501
4695
 
4502
- key_types = []
4503
- value_types = []
4696
+ key_types = [] #: Array[AST::Types::t]
4697
+ value_types = [] #: Array[AST::Types::t]
4504
4698
 
4505
- if AST::Builtin::Hash.instance_type?(hint)
4699
+ if hint && AST::Builtin::Hash.instance_type?(hint)
4700
+ # @type var hint: AST::Types::Name::Instance
4506
4701
  key_hint, value_hint = hint.args
4507
4702
  end
4508
4703
 
@@ -4511,7 +4706,7 @@ module Steep
4511
4706
  value_hint || AST::Builtin.any_type
4512
4707
  )
4513
4708
 
4514
- constr = self
4709
+ constr = self #: TypeConstruction
4515
4710
 
4516
4711
  if hash_node.children.empty?
4517
4712
  key_types << key_hint if key_hint
@@ -4528,14 +4723,13 @@ module Steep
4528
4723
  value_types << value_type
4529
4724
  when :kwsplat
4530
4725
  bypass_splat(elem) do |elem_|
4531
- pair = constr.synthesize(elem_, hint: hint_hash)
4532
-
4533
- if AST::Builtin::Hash.instance_type?(pair.type)
4534
- key_types << pair.type.args[0]
4535
- value_types << pair.type.args[1]
4726
+ constr.synthesize(elem_, hint: hint_hash).tap do |(type, _)|
4727
+ if AST::Builtin::Hash.instance_type?(type)
4728
+ # @type var type: AST::Types::Name::Instance
4729
+ key_types << type.args[0]
4730
+ value_types << type.args[1]
4731
+ end
4536
4732
  end
4537
-
4538
- pair
4539
4733
  end
4540
4734
  else
4541
4735
  raise
@@ -4573,7 +4767,7 @@ module Steep
4573
4767
 
4574
4768
  def save_typing
4575
4769
  typing.save!
4576
- with_new_typing(typing.parent)
4770
+ with_new_typing(typing.parent || raise)
4577
4771
  end
4578
4772
 
4579
4773
  def extract_outermost_call(node, var_name)