steep 0.31.0 → 0.35.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/lib/steep.rb +3 -2
  4. data/lib/steep/annotation_parser.rb +1 -1
  5. data/lib/steep/ast/types/factory.rb +66 -60
  6. data/lib/steep/cli.rb +15 -2
  7. data/lib/steep/drivers/print_project.rb +11 -0
  8. data/lib/steep/drivers/stats.rb +85 -0
  9. data/lib/steep/drivers/vendor.rb +1 -20
  10. data/lib/steep/errors.rb +19 -15
  11. data/lib/steep/interface/method_type.rb +12 -23
  12. data/lib/steep/method_name.rb +28 -0
  13. data/lib/steep/project/completion_provider.rb +24 -15
  14. data/lib/steep/project/dsl.rb +13 -17
  15. data/lib/steep/project/options.rb +4 -4
  16. data/lib/steep/project/source_file.rb +2 -1
  17. data/lib/steep/project/target.rb +19 -10
  18. data/lib/steep/server/interaction_worker.rb +1 -1
  19. data/lib/steep/server/utils.rb +1 -1
  20. data/lib/steep/source.rb +3 -3
  21. data/lib/steep/subtyping/check.rb +30 -16
  22. data/lib/steep/subtyping/variable_occurrence.rb +2 -0
  23. data/lib/steep/type_construction.rb +585 -416
  24. data/lib/steep/type_inference/context.rb +7 -3
  25. data/lib/steep/type_inference/context_array.rb +1 -1
  26. data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
  27. data/lib/steep/type_inference/logic_type_interpreter.rb +6 -0
  28. data/lib/steep/type_inference/method_call.rb +116 -0
  29. data/lib/steep/typing.rb +38 -8
  30. data/lib/steep/version.rb +1 -1
  31. data/smoke/regression/fun.rb +8 -0
  32. data/smoke/regression/fun.rbs +4 -0
  33. data/smoke/regression/range.rb +5 -0
  34. data/steep.gemspec +1 -1
  35. metadata +10 -6
  36. data/lib/steep/ast/buffer.rb +0 -51
  37. data/lib/steep/ast/location.rb +0 -86
@@ -147,7 +147,23 @@ module Steep
147
147
  success(constraints: constraints)
148
148
 
149
149
  when relation.super_type.is_a?(AST::Types::Boolean)
150
- success(constraints: constraints)
150
+ check(
151
+ Relation.new(sub_type: relation.sub_type, super_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type])),
152
+ self_type: self_type,
153
+ assumption: assumption,
154
+ trace: trace,
155
+ constraints: constraints
156
+ )
157
+
158
+ when relation.sub_type.is_a?(AST::Types::Boolean)
159
+ check(
160
+ Relation.new(sub_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type]),
161
+ super_type: relation.super_type),
162
+ self_type: self_type,
163
+ assumption: assumption,
164
+ trace: trace,
165
+ constraints: constraints
166
+ )
151
167
 
152
168
  when relation.sub_type.is_a?(AST::Types::Self) && !self_type.is_a?(AST::Types::Self)
153
169
  check(
@@ -326,23 +342,21 @@ module Steep
326
342
  constraints: constraints)
327
343
 
328
344
  when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
329
- if Set.new(relation.sub_type.elements.keys).superset?(Set.new(relation.super_type.elements.keys))
330
- keys = relation.super_type.elements.keys
331
- type_pairs = keys.map {|key| [relation.sub_type.elements[key], relation.super_type.elements[key]] }
332
- results = type_pairs.flat_map do |t1, t2|
333
- relation = Relation.new(sub_type: t1, super_type: t2)
334
- [check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints),
335
- check(relation.flip, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)]
336
- end
345
+ keys = relation.super_type.elements.keys
346
+ relations = keys.map {|key|
347
+ Relation.new(
348
+ sub_type: relation.sub_type.elements[key] || AST::Builtin.nil_type,
349
+ super_type: relation.super_type.elements[key]
350
+ )
351
+ }
352
+ results = relations.map do |relation|
353
+ check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
354
+ end
337
355
 
338
- if results.all?(&:success?)
339
- success(constraints: constraints)
340
- else
341
- results.find(&:failure?)
342
- end
356
+ if results.all?(&:success?)
357
+ success(constraints: constraints)
343
358
  else
344
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
345
- trace: trace)
359
+ results.find(&:failure?)
346
360
  end
347
361
 
348
362
  when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Name::Base)
@@ -29,6 +29,8 @@ module Steep
29
29
  returns << var
30
30
  end
31
31
  end
32
+
33
+ params.subtract(returns)
32
34
  end
33
35
 
34
36
  def each_var(type, &block)
@@ -131,7 +131,7 @@ module Steep
131
131
  definition_method_type = if definition
132
132
  definition.methods[method_name]&.yield_self do |method|
133
133
  method.method_types
134
- .map {|method_type| checker.factory.method_type(method_type, self_type: self_type) }
134
+ .map {|method_type| checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]) }
135
135
  .select {|method_type| method_type.is_a?(Interface::MethodType) }
136
136
  .inject {|t1, t2| t1 + t2}
137
137
  end
@@ -216,6 +216,21 @@ module Steep
216
216
 
217
217
  lvar_env = lvar_env.annotate(annots)
218
218
 
219
+ call_context = case self_type
220
+ when nil
221
+ TypeInference::MethodCall::UnknownContext.new()
222
+ when AST::Types::Name::Singleton
223
+ TypeInference::MethodCall::MethodContext.new(
224
+ method_name: SingletonMethodName.new(type_name: module_context.class_name, method_name: method_name)
225
+ )
226
+ when AST::Types::Name::Instance, AST::Types::Intersection
227
+ TypeInference::MethodCall::MethodContext.new(
228
+ method_name: InstanceMethodName.new(type_name: module_context.class_name, method_name: method_name)
229
+ )
230
+ else
231
+ raise "Unexpected self_type: #{self_type}"
232
+ end
233
+
219
234
  self.class.new(
220
235
  checker: checker,
221
236
  source: source,
@@ -227,7 +242,8 @@ module Steep
227
242
  break_context: nil,
228
243
  self_type: annots.self_type || self_type,
229
244
  type_env: type_env,
230
- lvar_env: lvar_env
245
+ lvar_env: lvar_env,
246
+ call_context: call_context
231
247
  ),
232
248
  typing: typing,
233
249
  )
@@ -355,7 +371,8 @@ module Steep
355
371
  module_context: module_context_,
356
372
  self_type: module_context_.module_type,
357
373
  type_env: module_type_env,
358
- lvar_env: lvar_env
374
+ lvar_env: lvar_env,
375
+ call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context_.class_name)
359
376
  )
360
377
  )
361
378
  end
@@ -424,7 +441,8 @@ module Steep
424
441
  break_context: nil,
425
442
  self_type: module_context.module_type,
426
443
  type_env: class_type_env,
427
- lvar_env: lvar_env
444
+ lvar_env: lvar_env,
445
+ call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
428
446
  )
429
447
 
430
448
  self.class.new(
@@ -509,7 +527,8 @@ module Steep
509
527
  break_context: nil,
510
528
  self_type: module_context.module_type,
511
529
  type_env: type_env,
512
- lvar_env: lvar_env
530
+ lvar_env: lvar_env,
531
+ call_context: TypeInference::MethodCall::ModuleContext.new(type_name: module_context.class_name)
513
532
  )
514
533
 
515
534
  self.class.new(
@@ -608,6 +627,22 @@ module Steep
608
627
  Pair.new(type: type, constr: constr)
609
628
  end
610
629
 
630
+ def add_call(call)
631
+ case call
632
+ when TypeInference::MethodCall::NoMethodError
633
+ typing.add_error(call.error)
634
+ when TypeInference::MethodCall::Error
635
+ call.errors.each do |error|
636
+ typing.add_error(error)
637
+ end
638
+ end
639
+
640
+ typing.add_typing(call.node, call.return_type, nil)
641
+ typing.add_call(call.node, call)
642
+
643
+ Pair.new(type: call.return_type, constr: self)
644
+ end
645
+
611
646
  def synthesize(node, hint: nil)
612
647
  Steep.logger.tagged "synthesize:(#{node.location.expression.to_s.split(/:/, 2).last})" do
613
648
  Steep.logger.debug node.type
@@ -786,28 +821,33 @@ module Steep
786
821
  when :super
787
822
  yield_self do
788
823
  if self_type && method_context&.method
789
- if method_context.super_method
824
+ if super_def = method_context.super_method
790
825
  each_child_node(node) do |child|
791
826
  synthesize(child)
792
827
  end
793
828
 
794
829
  super_method = Interface::Interface::Entry.new(
795
830
  method_types: method_context.super_method.method_types.map {|method_type|
796
- checker.factory.method_type(method_type, self_type: self_type)
831
+ decl = TypeInference::MethodCall::MethodDecl.new(
832
+ method_name: InstanceMethodName.new(type_name: super_def.implemented_in || super_def.defined_in,
833
+ method_name: method_context.name),
834
+ method_def: super_def
835
+ )
836
+ checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[decl])
797
837
  }
798
838
  )
799
839
  args = TypeInference::SendArgs.from_nodes(node.children.dup)
800
840
 
801
- return_type, _ = type_method_call(node,
802
- receiver_type: self_type,
803
- method_name: method_context.name,
804
- method: super_method,
805
- args: args,
806
- block_params: nil,
807
- block_body: nil,
808
- topdown_hint: true)
841
+ call, constr = type_method_call(node,
842
+ receiver_type: self_type,
843
+ method_name: method_context.name,
844
+ method: super_method,
845
+ args: args,
846
+ block_params: nil,
847
+ block_body: nil,
848
+ topdown_hint: true)
809
849
 
810
- add_typing node, type: return_type
850
+ constr.add_call(call)
811
851
  else
812
852
  fallback_to_any node do
813
853
  Errors::UnexpectedSuper.new(node: node, method: method_context.name)
@@ -1208,7 +1248,13 @@ module Steep
1208
1248
 
1209
1249
  when :class
1210
1250
  yield_self do
1211
- for_class(node).tap do |constructor|
1251
+ constr = self
1252
+
1253
+ name, sup, _ = node.children
1254
+ _, constr = constr.synthesize(name)
1255
+ _, constr = constr.synthesize(sup) if sup
1256
+
1257
+ constr.for_class(node).tap do |constructor|
1212
1258
  constructor.typing.add_context_for_node(node, context: constructor.context)
1213
1259
  constructor.typing.add_context_for_body(node, context: constructor.context)
1214
1260
 
@@ -1224,6 +1270,11 @@ module Steep
1224
1270
 
1225
1271
  when :module
1226
1272
  yield_self do
1273
+ constr = self
1274
+
1275
+ name, _ = node.children
1276
+ _, constr = constr.synthesize(name)
1277
+
1227
1278
  for_module(node).yield_self do |constructor|
1228
1279
  constructor.typing.add_context_for_node(node, context: constructor.context)
1229
1280
  constructor.typing.add_context_for_body(node, context: constructor.context)
@@ -1271,24 +1322,39 @@ module Steep
1271
1322
  when :self
1272
1323
  add_typing node, type: AST::Types::Self.new
1273
1324
 
1325
+ when :cbase
1326
+ add_typing node, type: AST::Types::Void.new
1327
+
1274
1328
  when :const
1275
- const_name = module_name_from_node(node)
1329
+ parent = node.children[0]
1330
+ if parent
1331
+ _, constr = synthesize(parent)
1332
+ else
1333
+ constr = self
1334
+ end
1335
+
1336
+ const_name = constr.module_name_from_node(node)
1276
1337
 
1277
1338
  if const_name
1278
1339
  type = type_env.get(const: const_name) do
1279
- fallback_to_any node
1340
+ constr.fallback_to_any(node)
1280
1341
  end
1281
- add_typing node, type: type
1342
+ constr.add_typing(node, type: type)
1282
1343
  else
1283
- fallback_to_any node
1344
+ constr.fallback_to_any(node)
1284
1345
  end
1285
1346
 
1286
1347
  when :casgn
1287
1348
  yield_self do
1288
- const_name = module_name_from_node(node)
1349
+ constr = self
1350
+
1351
+ parent = node.children[0]
1352
+ _, constr = constr.synthesize(parent) if parent
1353
+ const_name = constr.module_name_from_node(node)
1354
+
1289
1355
  if const_name
1290
1356
  const_type = type_env.get(const: const_name) {}
1291
- value_type = synthesize(node.children.last, hint: const_type).type
1357
+ value_type, constr = constr.synthesize(node.children.last, hint: const_type)
1292
1358
  type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
1293
1359
  case error
1294
1360
  when Subtyping::Result::Failure
@@ -1302,10 +1368,10 @@ module Steep
1302
1368
  end
1303
1369
  end
1304
1370
 
1305
- add_typing(node, type: type)
1371
+ constr.add_typing(node, type: type)
1306
1372
  else
1307
- synthesize(node.children.last).type
1308
- fallback_to_any(node)
1373
+ _, constr = constr.synthesize(node.children.last)
1374
+ constr.fallback_to_any(node)
1309
1375
  end
1310
1376
  end
1311
1377
 
@@ -1338,7 +1404,7 @@ module Steep
1338
1404
  if method_context&.method
1339
1405
  if method_context.super_method
1340
1406
  types = method_context.super_method.method_types.map {|method_type|
1341
- checker.factory.method_type(method_type, self_type: self_type).return_type
1407
+ checker.factory.method_type(method_type, self_type: self_type, method_decls: Set[]).return_type
1342
1408
  }
1343
1409
  add_typing(node, type: union_type(*types))
1344
1410
  else
@@ -2029,7 +2095,7 @@ module Steep
2029
2095
  unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
2030
2096
  # Steep.logger.error { "result = #{pair.inspect}" }
2031
2097
  # Steep.logger.error { "node = #{node.type}" }
2032
- raise "#synthesize should return an instance of Pair: #{pair.class}"
2098
+ raise "#synthesize should return an instance of Pair: #{pair.class}, node=#{node.inspect}"
2033
2099
  end
2034
2100
  end
2035
2101
  end
@@ -2273,177 +2339,225 @@ module Steep
2273
2339
  return_hint = type_hint.return_type
2274
2340
  end
2275
2341
 
2276
- block_pair = type_block(node: node,
2277
- block_param_hint: params_hint,
2278
- block_type_hint: return_hint,
2279
- node_type_hint: nil,
2280
- block_params: params,
2281
- block_body: block_body,
2282
- block_annotations: block_annotations,
2283
- topdown_hint: true)
2342
+ block_constr = for_block(
2343
+ block_params: params,
2344
+ block_param_hint: params_hint,
2345
+ block_annotations: block_annotations,
2346
+ node_type_hint: nil
2347
+ )
2284
2348
 
2285
- add_typing node, type: block_pair.type
2286
- end
2349
+ block_constr.typing.add_context_for_body(node, context: block_constr.context)
2287
2350
 
2288
- def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2289
- receiver, method_name, *arguments = send_node.children
2290
- receiver_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2351
+ params.params.each do |param|
2352
+ _, block_constr = block_constr.synthesize(param.node, hint: param.type)
2353
+ end
2291
2354
 
2292
- if unwrap
2293
- receiver_type = unwrap(receiver_type)
2355
+ if block_body
2356
+ return_type = block_constr.synthesize_block(
2357
+ node: node,
2358
+ block_body: block_body,
2359
+ topdown_hint: true,
2360
+ block_type_hint: return_hint
2361
+ ) do |error|
2362
+ typing.add_error(error)
2363
+ end
2364
+ else
2365
+ return_type = AST::Builtin.any_type
2294
2366
  end
2295
2367
 
2296
- receiver_type = expand_alias(receiver_type)
2368
+ block_type = AST::Types::Proc.new(
2369
+ params: params_hint || params.params_type,
2370
+ return_type: return_type
2371
+ )
2297
2372
 
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
2373
+ add_typing node, type: block_type
2374
+ end
2305
2375
 
2306
- add_typing node, type: AST::Builtin.any_type
2376
+ def synthesize_children(node, skips: [])
2377
+ skips = Set.new.compare_by_identity.merge(skips)
2307
2378
 
2308
- when nil
2309
- fallback_to_any node
2379
+ constr = self
2310
2380
 
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
2381
+ each_child_node(node) do |child|
2382
+ unless skips.include?(child)
2383
+ _, constr = constr.synthesize(child)
2384
+ end
2385
+ end
2315
2386
 
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
2387
+ constr
2388
+ end
2355
2389
 
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
2390
+ def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:)
2391
+ method = interface.methods[method_name]
2362
2392
 
2363
- case type
2364
- when nil, Errors::Base
2365
- arguments.each do |arg|
2366
- unless typing.has_type?(arg)
2367
- if arg.type == :splat
2368
- type, constr = constr.synthesize(arg.children[0])
2369
- add_typing(arg, type: AST::Builtin::Array.instance_type(type))
2370
- else
2371
- _, constr = constr.synthesize(arg)
2393
+ if method
2394
+ args = TypeInference::SendArgs.from_nodes(arguments)
2395
+ call, constr = type_method_call(node,
2396
+ method: method,
2397
+ method_name: method_name,
2398
+ args: args,
2399
+ block_params: block_params,
2400
+ block_body: block_body,
2401
+ receiver_type: receiver_type,
2402
+ topdown_hint: true)
2403
+
2404
+ if call && constr
2405
+ case method_name.to_s
2406
+ when "[]=", /\w=\Z/
2407
+ if typing.has_type?(arguments.last)
2408
+ call = call.with_return_type(typing.type_of(node: arguments.last))
2372
2409
  end
2373
2410
  end
2374
- end
2375
-
2376
- if block_body && block_params
2377
- unless typing.has_type?(block_body)
2378
- block_annotations = source.annotations(block: node, builder: checker.builder, current_module: current_namespace)
2379
- params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2380
- pairs = params.each.map {|param| [param, AST::Builtin.any_type]}
2411
+ else
2412
+ error = Errors::UnresolvedOverloading.new(
2413
+ node: node,
2414
+ receiver_type: receiver_type,
2415
+ method_name: method_name,
2416
+ method_types: method.method_types
2417
+ )
2418
+ call = TypeInference::MethodCall::Error.new(
2419
+ node: node,
2420
+ context: context.method_context,
2421
+ method_name: method_name,
2422
+ receiver_type: receiver_type,
2423
+ errors: [error]
2424
+ )
2381
2425
 
2382
- for_block, _ = constr.for_block(block_annotations: block_annotations,
2383
- param_pairs: pairs,
2384
- method_return_type: AST::Builtin.any_type,
2385
- typing: typing)
2426
+ skips = [receiver]
2427
+ skips << node.children[0] if node.type == :block
2386
2428
 
2387
- for_block.typing.add_context_for_body(node, context: for_block.context)
2429
+ constr = synthesize_children(node, skips: skips)
2430
+ if block_params
2431
+ block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2388
2432
 
2389
- for_block.synthesize(block_body)
2433
+ constr.type_block_without_hint(
2434
+ node: node,
2435
+ block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
2436
+ block_annotations: block_annotations,
2437
+ block_body: block_body
2438
+ ) do |error|
2439
+ constr.typing.add_error(error)
2440
+ end
2390
2441
  end
2391
2442
  end
2443
+
2444
+ constr.add_call(call)
2392
2445
  else
2393
- Pair.new(type: type, constr: constr)
2446
+ add_call(
2447
+ TypeInference::MethodCall::NoMethodError.new(
2448
+ node: node,
2449
+ context: context.method_context,
2450
+ method_name: method_name,
2451
+ receiver_type: receiver_type,
2452
+ error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2453
+ )
2454
+ )
2394
2455
  end
2395
2456
  end
2396
2457
 
2397
- def for_block(block_annotations:, param_pairs:, method_return_type:, typing:)
2398
- block_type_env = type_env.dup.yield_self do |env|
2399
- param_pairs.each do |param, type|
2400
- if param.type
2401
- env.set(lvar: param.var.name, type: param.type)
2402
- else
2403
- env.set(lvar: param.var.name, type: type)
2404
- end
2405
- end
2458
+ def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2459
+ receiver, method_name, *arguments = send_node.children
2460
+ recv_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2406
2461
 
2407
- env.with_annotations(
2408
- lvar_types: block_annotations.lvar_types,
2409
- ivar_types: block_annotations.ivar_types,
2410
- const_types: block_annotations.const_types,
2411
- )
2462
+ if unwrap
2463
+ recv_type = unwrap(recv_type)
2412
2464
  end
2413
2465
 
2414
- lvar_env = context.lvar_env.pin_assignments.annotate(block_annotations)
2466
+ receiver_type = checker.factory.deep_expand_alias(recv_type)
2415
2467
 
2416
- return_type = if block_annotations.break_type
2417
- union_type(method_return_type, block_annotations.break_type)
2418
- else
2419
- method_return_type
2420
- end
2421
- Steep.logger.debug("return_type = #{return_type}")
2468
+ type, constr = case receiver_type
2469
+ when nil
2470
+ raise
2422
2471
 
2423
- block_context = TypeInference::Context::BlockContext.new(body_type: block_annotations.block_type)
2424
- Steep.logger.debug("block_context { body_type: #{block_context.body_type} }")
2472
+ when AST::Types::Any
2473
+ constr = constr.synthesize_children(node, skips: [receiver])
2474
+ constr.add_call(
2475
+ TypeInference::MethodCall::Untyped.new(
2476
+ node: node,
2477
+ context: context.method_context,
2478
+ method_name: method_name
2479
+ )
2480
+ )
2425
2481
 
2426
- break_context = TypeInference::Context::BreakContext.new(
2427
- break_type: block_annotations.break_type || method_return_type,
2428
- next_type: block_annotations.block_type
2429
- )
2430
- Steep.logger.debug("break_context { type: #{break_context.break_type} }")
2482
+ when AST::Types::Void, AST::Types::Bot, AST::Types::Top, AST::Types::Var
2483
+ constr = constr.synthesize_children(node, skips: [receiver])
2484
+ constr.add_call(
2485
+ TypeInference::MethodCall::NoMethodError.new(
2486
+ node: node,
2487
+ context: context.method_context,
2488
+ method_name: method_name,
2489
+ receiver_type: receiver_type,
2490
+ error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2491
+ )
2492
+ )
2431
2493
 
2432
- [self.class.new(
2433
- checker: checker,
2434
- source: source,
2435
- annotations: annotations.merge_block_annotations(block_annotations),
2436
- typing: typing,
2437
- context: TypeInference::Context.new(
2438
- block_context: block_context,
2439
- method_context: method_context,
2440
- module_context: module_context,
2441
- break_context: break_context,
2442
- self_type: block_annotations.self_type || self_type,
2443
- type_env: block_type_env,
2444
- lvar_env: lvar_env
2494
+ when AST::Types::Self
2495
+ expanded_self = expand_self(receiver_type)
2496
+
2497
+ if expanded_self.is_a?(AST::Types::Self)
2498
+ Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
2499
+
2500
+ constr = constr.synthesize_children(node, skips: [receiver])
2501
+ constr.add_call(
2502
+ TypeInference::MethodCall::NoMethodError.new(
2503
+ node: node,
2504
+ context: context.method_context,
2505
+ method_name: method_name,
2506
+ receiver_type: receiver_type,
2507
+ error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2508
+ )
2509
+ )
2510
+ else
2511
+ interface = checker.factory.interface(expanded_self,
2512
+ private: !receiver,
2513
+ self_type: AST::Types::Self.new)
2514
+
2515
+ constr.type_send_interface(node,
2516
+ interface: interface,
2517
+ receiver: receiver,
2518
+ receiver_type: expanded_self,
2519
+ method_name: method_name,
2520
+ arguments: arguments,
2521
+ block_params: block_params,
2522
+ block_body: block_body)
2523
+ end
2524
+ else
2525
+ interface = checker.factory.interface(receiver_type,
2526
+ private: !receiver,
2527
+ self_type: receiver_type)
2528
+
2529
+ constr.type_send_interface(node,
2530
+ interface: interface,
2531
+ receiver: receiver,
2532
+ receiver_type: receiver_type,
2533
+ method_name: method_name,
2534
+ arguments: arguments,
2535
+ block_params: block_params,
2536
+ block_body: block_body)
2537
+ end
2538
+
2539
+ Pair.new(type: type, constr: constr)
2540
+ rescue => exn
2541
+ case exn
2542
+ when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2543
+ # ignore known RBS errors.
2544
+ else
2545
+ Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2546
+ end
2547
+
2548
+ error = Errors::UnexpectedError.new(node: node, error: exn)
2549
+
2550
+ type_any_rec(node)
2551
+
2552
+ add_call(
2553
+ TypeInference::MethodCall::Error.new(
2554
+ node: node,
2555
+ context: context.method_context,
2556
+ method_name: method_name,
2557
+ receiver_type: receiver_type,
2558
+ errors: [error]
2445
2559
  )
2446
- ), return_type]
2560
+ )
2447
2561
  end
2448
2562
 
2449
2563
  def expand_self(type)
@@ -2463,63 +2577,54 @@ module Steep
2463
2577
 
2464
2578
  zips.map do |arg_pairs|
2465
2579
  typing.new_child(node_range) do |child_typing|
2466
- ret = self.with_new_typing(child_typing).try_method_type(
2580
+ self.with_new_typing(child_typing).try_method_type(
2467
2581
  node,
2468
2582
  receiver_type: receiver_type,
2583
+ method_name: method_name,
2469
2584
  method_type: method_type,
2470
2585
  args: args,
2471
2586
  arg_pairs: arg_pairs,
2472
2587
  block_params: block_params,
2473
2588
  block_body: block_body,
2474
- child_typing: child_typing,
2475
2589
  topdown_hint: topdown_hint
2476
2590
  )
2477
-
2478
- raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2479
-
2480
- result, constr = ret
2481
-
2482
- [result, constr, method_type]
2483
2591
  end
2484
2592
  end
2485
2593
  end
2486
2594
  end
2487
2595
 
2488
- unless results.empty?
2489
- result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2490
- else
2596
+ case
2597
+ when results.empty?
2491
2598
  method_type = method.method_types.last
2599
+ all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
2600
+ set.merge(method_type.method_decls)
2601
+ end
2602
+ error = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
2603
+ call = TypeInference::MethodCall::Error.new(
2604
+ node: node,
2605
+ context: context.method_context,
2606
+ method_name: method_name,
2607
+ receiver_type: receiver_type,
2608
+ return_type: method_type.return_type,
2609
+ errors: [error],
2610
+ method_decls: all_decls
2611
+ )
2492
2612
  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
2613
+ when (call, constr = results.find {|call, _| call.is_a?(TypeInference::MethodCall::Typed) })
2614
+ # Nop
2615
+ else
2616
+ if results.one?
2617
+ call, constr = results[0]
2507
2618
  else
2508
- typing.add_error Errors::UnresolvedOverloading.new(node: node,
2509
- receiver_type: expand_self(receiver_type),
2510
- method_name: method_name,
2511
- method_types: method.method_types)
2512
- type = AST::Builtin.any_type
2619
+ return
2513
2620
  end
2514
-
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]
2522
2621
  end
2622
+ constr.typing.save!
2623
+
2624
+ [
2625
+ call,
2626
+ update_lvar_env { constr.context.lvar_env }
2627
+ ]
2523
2628
  end
2524
2629
 
2525
2630
  def check_keyword_arg(receiver_type:, node:, method_type:, constraints:)
@@ -2621,14 +2726,12 @@ module Steep
2621
2726
 
2622
2727
  hash_type = AST::Builtin::Hash.instance_type(
2623
2728
  AST::Builtin::Symbol.instance_type,
2624
- AST::Types::Union.build(types: value_types,
2625
- location: method_type.location)
2729
+ AST::Types::Union.build(types: value_types)
2626
2730
  )
2627
2731
  else
2628
2732
  hash_elements = params.required_keywords.merge(
2629
2733
  method_type.params.optional_keywords.transform_values do |type|
2630
- AST::Types::Union.build(types: [type, AST::Builtin.nil_type],
2631
- location: method_type.location)
2734
+ AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
2632
2735
  end
2633
2736
  )
2634
2737
 
@@ -2650,151 +2753,211 @@ module Steep
2650
2753
  nil
2651
2754
  end
2652
2755
 
2653
- def try_method_type(node, receiver_type:, method_type:, args:, arg_pairs:, block_params:, block_body:, child_typing:, topdown_hint:)
2756
+ def try_method_type(node, receiver_type:, method_name:, method_type:, args:, arg_pairs:, block_params:, block_body:, topdown_hint:)
2654
2757
  fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x)}
2655
2758
  fresh_vars = Set.new(fresh_types.map(&:name))
2656
2759
  instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
2657
2760
 
2658
- construction = self.class.new(
2659
- checker: checker,
2660
- source: source,
2661
- annotations: annotations,
2662
- typing: child_typing,
2663
- context: context
2664
- )
2761
+ constr = self
2665
2762
 
2666
- constr = construction
2763
+ method_type = method_type.instantiate(instantiation)
2667
2764
 
2668
- method_type.instantiate(instantiation).yield_self do |method_type|
2669
- constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
2670
- variance = Subtyping::VariableVariance.from_method_type(method_type)
2671
- occurence = Subtyping::VariableOccurence.from_method_type(method_type)
2765
+ constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
2766
+ variance = Subtyping::VariableVariance.from_method_type(method_type)
2767
+ occurence = Subtyping::VariableOccurence.from_method_type(method_type)
2672
2768
 
2673
- arg_pairs.each do |pair|
2674
- case pair
2675
- when Array
2676
- (arg_node, param_type) = pair
2677
- param_type = param_type.subst(instantiation)
2769
+ errors = []
2678
2770
 
2679
- arg_type, constr = if arg_node.type == :splat
2680
- constr.synthesize(arg_node.children[0])
2681
- else
2682
- constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2683
- end
2771
+ arg_pairs.each do |pair|
2772
+ case pair
2773
+ when Array
2774
+ arg_node, param_type = pair
2775
+ param_type = param_type.subst(instantiation)
2776
+
2777
+ arg_type, constr = if arg_node.type == :splat
2778
+ constr.synthesize(arg_node.children[0])
2779
+ else
2780
+ constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2781
+ end
2684
2782
 
2685
- check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do |result|
2686
- return [Errors::ArgumentTypeMismatch.new(node: arg_node,
2783
+ check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do
2784
+ errors << Errors::ArgumentTypeMismatch.new(node: arg_node,
2687
2785
  receiver_type: receiver_type,
2688
2786
  expected: param_type,
2689
- actual: arg_type),
2690
- constr]
2691
- end
2692
- else
2693
- # keyword
2694
- result = check_keyword_arg(receiver_type: receiver_type,
2695
- node: pair,
2696
- method_type: method_type,
2697
- constraints: constraints)
2787
+ actual: arg_type)
2788
+ end
2789
+ else
2790
+ # keyword
2791
+ result = constr.check_keyword_arg(receiver_type: receiver_type,
2792
+ node: pair,
2793
+ method_type: method_type,
2794
+ constraints: constraints)
2698
2795
 
2699
- if result.is_a?(Errors::Base)
2700
- return [result, constr]
2701
- end
2796
+ if result.is_a?(Errors::Base)
2797
+ errors << result
2702
2798
  end
2703
2799
  end
2800
+ end
2704
2801
 
2705
- if block_params && method_type.block
2706
- block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2707
- block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2708
-
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
- ]
2802
+ if block_params
2803
+ # block is given
2804
+ block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2805
+ block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2806
+
2807
+ if method_type.block
2808
+ pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
2809
+
2810
+ if pairs
2811
+ begin
2812
+ block_constr = constr.for_block(
2813
+ block_params: block_params_,
2814
+ block_param_hint: method_type.block.type.params,
2815
+ block_annotations: block_annotations,
2816
+ node_type_hint: method_type.return_type
2817
+ )
2818
+ block_constr = block_constr.with_new_typing(
2819
+ block_constr.typing.new_child(
2820
+ range: block_constr.typing.block_range(node)
2821
+ )
2822
+ )
2823
+
2824
+ block_constr.typing.add_context_for_body(node, context: block_constr.context)
2825
+
2826
+ pairs.each do |param, type|
2827
+ _, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
2828
+
2829
+ if param.type
2830
+ check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
2831
+ error = Errors::IncompatibleAssignment.new(
2832
+ node: param.node,
2833
+ lhs_type: param.type,
2834
+ rhs_type: type,
2835
+ result: result
2836
+ )
2837
+ errors << error
2838
+ end
2839
+ end
2740
2840
  end
2741
- end
2742
- end
2743
- end
2744
2841
 
2745
- case
2746
- when method_type.block && block_params
2747
- Steep.logger.debug "block is okay: method_type=#{method_type}"
2748
- Steep.logger.debug "Constraints = #{constraints}"
2749
-
2750
- begin
2751
- method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
2752
- type, _ = constr.type_block(node: node,
2753
- block_param_hint: method_type.block.type.params,
2754
- block_type_hint: method_type.block.type.return_type,
2755
- node_type_hint: method_type.return_type,
2756
- block_params: block_params_,
2757
- block_body: block_body,
2758
- block_annotations: block_annotations,
2759
- topdown_hint: topdown_hint)
2760
-
2761
- result = check_relation(sub_type: type.return_type,
2842
+ s = constraints.solution(
2843
+ checker,
2844
+ self_type: self_type,
2845
+ variance: variance,
2846
+ variables: method_type.params.free_variables + method_type.block.type.params.free_variables
2847
+ )
2848
+ method_type = method_type.subst(s)
2849
+ block_constr = block_constr.update_lvar_env {|env| env.subst(s) }
2850
+ if block_body
2851
+ block_body_type = block_constr.synthesize_block(
2852
+ node: node,
2853
+ block_type_hint: method_type.block.type.return_type,
2854
+ block_body: block_body,
2855
+ topdown_hint: topdown_hint
2856
+ ) do |error|
2857
+ errors << error
2858
+ end
2859
+ else
2860
+ block_body_type = AST::Builtin.nil_type
2861
+ end
2862
+
2863
+ result = check_relation(sub_type: block_body_type,
2762
2864
  super_type: method_type.block.type.return_type,
2763
2865
  constraints: constraints)
2764
2866
 
2765
2867
  case result
2766
2868
  when Subtyping::Result::Success
2767
- method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)).yield_self do |ret_type|
2768
- ty = if block_annotations.break_type
2769
- AST::Types::Union.new(types: [block_annotations.break_type, ret_type])
2770
- else
2771
- ret_type
2772
- end
2773
- [ty, constr]
2869
+ s = constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)
2870
+ method_type = method_type.subst(s)
2871
+
2872
+ return_type = method_type.return_type
2873
+ if break_type = block_annotations.break_type
2874
+ return_type = union_type(break_type, return_type)
2774
2875
  end
2775
2876
 
2776
2877
  when Subtyping::Result::Failure
2777
- [Errors::BlockTypeMismatch.new(node: node,
2778
- expected: method_type.block.type,
2779
- actual: type,
2780
- result: result),
2781
- constr]
2878
+ block_type = AST::Types::Proc.new(
2879
+ params: method_type.block.type.params || block_params.params_type,
2880
+ return_type: block_body_type
2881
+ )
2882
+ errors << Errors::BlockTypeMismatch.new(node: node,
2883
+ expected: method_type.block.type,
2884
+ actual: block_type,
2885
+ result: result)
2886
+
2887
+ return_type = method_type.return_type
2888
+ end
2889
+
2890
+ block_constr.typing.save!
2891
+ rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2892
+ errors << Errors::UnsatisfiableConstraint.new(
2893
+ node: node,
2894
+ method_type: method_type,
2895
+ var: exn.var,
2896
+ sub_type: exn.sub_type,
2897
+ super_type: exn.super_type,
2898
+ result: exn.result
2899
+ )
2900
+
2901
+ constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
2902
+ errors << error
2782
2903
  end
2904
+
2905
+ s = Interface::Substitution.build(method_type.free_variables,
2906
+ Array.new(method_type.free_variables.size, AST::Builtin.any_type))
2907
+ method_type = method_type.subst(s)
2783
2908
  end
2909
+ else
2910
+ errors << Errors::UnsupportedSyntax.new(
2911
+ node: block_params,
2912
+ message: "Unsupported block params pattern, probably masgn?"
2913
+ )
2914
+
2915
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2916
+ method_type = method_type.subst(s)
2917
+ end
2918
+ else
2919
+ # Block is given but method doesn't accept
2920
+ #
2921
+ constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
2922
+ errors << error
2923
+ end
2924
+
2925
+ errors << Errors::UnexpectedBlockGiven.new(
2926
+ node: node,
2927
+ method_type: method_type
2928
+ )
2929
+ end
2930
+ else
2931
+ # block is not given
2932
+ if (!method_type.block || method_type.block.optional?)
2933
+ # Method call without block is allowed
2934
+ unless args.block_pass_arg
2935
+ # OK, without block
2936
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2937
+ method_type = method_type.subst(s)
2938
+ else
2939
+ # &block arg is given
2940
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2941
+ method_type = method_type.subst(s)
2784
2942
 
2785
- rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2786
- [Errors::UnsatisfiableConstraint.new(node: node,
2787
- method_type: method_type,
2788
- var: exn.var,
2789
- sub_type: exn.sub_type,
2790
- super_type: exn.super_type,
2791
- result: exn.result),
2792
- constr]
2943
+ errors << Errors::UnexpectedBlockGiven.new(
2944
+ node: node,
2945
+ method_type: method_type
2946
+ )
2793
2947
  end
2948
+ else
2949
+ unless args.block_pass_arg
2950
+ # Required block is missing
2951
+ errors << Errors::RequiredBlockMissing.new(
2952
+ node: node,
2953
+ method_type: method_type
2954
+ )
2794
2955
 
2795
- when method_type.block && args.block_pass_arg
2796
- begin
2797
- method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
2956
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2957
+ method_type = method_type.subst(s)
2958
+ else
2959
+ begin
2960
+ method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params))
2798
2961
  block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
2799
2962
  result = check_relation(
2800
2963
  sub_type: block_type,
@@ -2808,68 +2971,65 @@ module Steep
2808
2971
  constraints: constraints
2809
2972
  )
2810
2973
 
2811
- case result
2812
- when Subtyping::Result::Success
2813
- [
2814
- method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)),
2815
- constr
2816
- ]
2817
-
2818
- when Subtyping::Result::Failure
2819
- [
2820
- Errors::BlockTypeMismatch.new(node: node,
2821
- expected: method_type.block.type,
2822
- actual: block_type,
2823
- result: result),
2824
- constr
2825
- ]
2974
+ result.else do |result|
2975
+ errors << Errors::BlockTypeMismatch.new(node: node,
2976
+ expected: method_type.block.type,
2977
+ actual: block_type,
2978
+ result: result)
2826
2979
  end
2980
+
2981
+ method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: method_type.free_variables))
2827
2982
  end
2983
+ end
2984
+ end
2985
+ end
2828
2986
 
2829
- rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2830
- [
2831
- Errors::UnsatisfiableConstraint.new(node: node,
2832
- method_type: method_type,
2833
- var: exn.var,
2834
- sub_type: exn.sub_type,
2835
- super_type: exn.super_type,
2836
- result: exn.result),
2837
- constr
2838
- ]
2839
- end
2840
-
2841
- when (!method_type.block || method_type.block.optional?) && !block_params && !block_body && !args.block_pass_arg
2842
- # OK, without block
2843
- [
2844
- method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)).return_type,
2845
- constr
2846
- ]
2847
-
2848
- when !method_type.block && (block_params || args.block_pass_arg)
2849
- [
2850
- Errors::UnexpectedBlockGiven.new(
2851
- node: node,
2852
- method_type: method_type
2853
- ),
2854
- constr
2855
- ]
2987
+ call = if errors.empty?
2988
+ TypeInference::MethodCall::Typed.new(
2989
+ node: node,
2990
+ context: context.method_context,
2991
+ receiver_type: receiver_type,
2992
+ method_name: method_name,
2993
+ actual_method_type: method_type,
2994
+ return_type: return_type || method_type.return_type,
2995
+ method_decls: method_type.method_decls
2996
+ )
2997
+ else
2998
+ TypeInference::MethodCall::Error.new(
2999
+ node: node,
3000
+ context: context.method_context,
3001
+ receiver_type: receiver_type,
3002
+ method_name: method_name,
3003
+ return_type: return_type || method_type.return_type,
3004
+ method_decls: method_type.method_decls,
3005
+ errors: errors
3006
+ )
3007
+ end
3008
+
3009
+ [
3010
+ call,
3011
+ constr
3012
+ ]
3013
+ end
3014
+
3015
+ def type_block_without_hint(node:, block_annotations:, block_params:, block_body:, &block)
3016
+ block_constr = for_block(
3017
+ block_params: block_params,
3018
+ block_param_hint: nil,
3019
+ block_annotations: block_annotations,
3020
+ node_type_hint: nil
3021
+ )
2856
3022
 
2857
- when method_type.block && !method_type.block.optional? && !block_params && !block_body && !args.block_pass_arg
2858
- [
2859
- Errors::RequiredBlockMissing.new(
2860
- node: node,
2861
- method_type: method_type
2862
- ),
2863
- constr
2864
- ]
3023
+ block_constr.typing.add_context_for_body(node, context: block_constr.context)
2865
3024
 
2866
- else
2867
- raise "Unexpected case condition"
2868
- end
3025
+ block_params.params.each do |param|
3026
+ _, block_constr = block_constr.synthesize(param.node, hint: param.type)
2869
3027
  end
3028
+
3029
+ block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body, topdown_hint: false, &block)
2870
3030
  end
2871
3031
 
2872
- def type_block(node:, block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
3032
+ def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
2873
3033
  block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
2874
3034
 
2875
3035
  param_types_hash = {}
@@ -2885,30 +3045,30 @@ module Steep
2885
3045
  end
2886
3046
  end
2887
3047
 
2888
- lvar_env = context.lvar_env.pin_assignments.yield_self do |env|
2889
- decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2890
- hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2891
- end
2892
- env.except(decls.keys).update(assigned_types: decls)
2893
- end.annotate(block_annotations)
3048
+ decls = param_types_hash.each.with_object({}) do |(name, type), hash|
3049
+ hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
3050
+ end
3051
+ lvar_env = context.lvar_env
3052
+ .pin_assignments
3053
+ .except(decls.keys)
3054
+ .update(assigned_types: decls)
3055
+ .annotate(block_annotations)
2894
3056
 
2895
3057
  break_type = if block_annotations.break_type
2896
3058
  union_type(node_type_hint, block_annotations.break_type)
2897
3059
  else
2898
3060
  node_type_hint
2899
3061
  end
2900
- Steep.logger.debug("return_type = #{break_type}")
2901
-
2902
- block_context = TypeInference::Context::BlockContext.new(body_type: block_annotations.block_type)
2903
- Steep.logger.debug("block_context { body_type: #{block_context.body_type} }")
2904
3062
 
3063
+ block_context = TypeInference::Context::BlockContext.new(
3064
+ body_type: block_annotations.block_type
3065
+ )
2905
3066
  break_context = TypeInference::Context::BreakContext.new(
2906
3067
  break_type: break_type,
2907
3068
  next_type: block_context.body_type
2908
3069
  )
2909
- Steep.logger.debug("break_context { type: #{break_context.break_type} }")
2910
3070
 
2911
- for_block_body = self.class.new(
3071
+ self.class.new(
2912
3072
  checker: checker,
2913
3073
  source: source,
2914
3074
  annotations: annotations.merge_block_annotations(block_annotations),
@@ -2920,37 +3080,34 @@ module Steep
2920
3080
  break_context: break_context,
2921
3081
  self_type: block_annotations.self_type || self_type,
2922
3082
  type_env: type_env.dup,
2923
- lvar_env: lvar_env
3083
+ lvar_env: lvar_env,
3084
+ call_context: self.context.call_context
2924
3085
  )
2925
3086
  )
3087
+ end
2926
3088
 
2927
- for_block_body.typing.add_context_for_body(node, context: for_block_body.context)
2928
-
3089
+ def synthesize_block(node:, block_type_hint:, block_body:, topdown_hint:)
2929
3090
  if block_body
2930
- body_pair = if (body_type = block_context.body_type)
2931
- for_block_body.check(block_body, body_type) do |expected, actual, result|
2932
- typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
2933
- expected: expected,
2934
- actual: actual,
2935
- result: result)
2936
-
2937
- end
2938
- else
2939
- for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
2940
- end
3091
+ body_type, _, context =
3092
+ if (body_type = block_context.body_type)
3093
+ check(block_body, body_type) do |expected, actual, result|
3094
+ error = Errors::BlockTypeMismatch.new(node: block_body,
3095
+ expected: expected,
3096
+ actual: actual,
3097
+ result: result)
3098
+ yield(error) if block_given?
3099
+ end
3100
+ else
3101
+ synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
3102
+ end
2941
3103
 
2942
3104
  range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
2943
- typing.add_context(range, context: body_pair.context)
3105
+ typing.add_context(range, context: context)
3106
+
3107
+ body_type
2944
3108
  else
2945
- body_pair = Pair.new(type: AST::Builtin.nil_type, constr: for_block_body)
3109
+ AST::Builtin.nil_type
2946
3110
  end
2947
-
2948
- body_pair.with(
2949
- type: AST::Types::Proc.new(
2950
- params: block_param_hint || block_params.params_type,
2951
- return_type: body_pair.type
2952
- )
2953
- )
2954
3111
  end
2955
3112
 
2956
3113
  def each_child_node(node)
@@ -3070,8 +3227,10 @@ module Steep
3070
3227
  end
3071
3228
  end
3072
3229
  expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
3073
- if method.implemented_in == module_context.module_definition.type_name
3074
- set << name
3230
+ if name != :new
3231
+ if method.implemented_in == module_context.module_definition.type_name
3232
+ set << name
3233
+ end
3075
3234
  end
3076
3235
  end
3077
3236
 
@@ -3172,6 +3331,14 @@ module Steep
3172
3331
  !nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
3173
3332
  end
3174
3333
 
3334
+ def type_any_rec(node)
3335
+ add_typing node, type: AST::Builtin.any_type
3336
+
3337
+ each_child_node(node) do |child|
3338
+ type_any_rec(child)
3339
+ end
3340
+ end
3341
+
3175
3342
  def fallback_any_rec(node)
3176
3343
  fallback_to_any(node) unless typing.has_type?(node)
3177
3344
 
@@ -3324,6 +3491,8 @@ module Steep
3324
3491
  end
3325
3492
 
3326
3493
  def try_hash_type(node, hint)
3494
+ hint = expand_alias(hint)
3495
+
3327
3496
  case hint
3328
3497
  when AST::Types::Record
3329
3498
  typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|