steep 0.31.0 → 0.35.0

Sign up to get free protection for your applications and to get access to all the features.
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|