steep 0.33.0 → 0.34.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.
@@ -774,16 +774,14 @@ module Steep
774
774
  attr_reader :params
775
775
  attr_reader :block
776
776
  attr_reader :return_type
777
- attr_reader :location
778
- attr_reader :method_def
777
+ attr_reader :method_decls
779
778
 
780
- def initialize(type_params:, params:, block:, return_type:, location:, method_def:)
779
+ def initialize(type_params:, params:, block:, return_type:, method_decls:)
781
780
  @type_params = type_params
782
781
  @params = params
783
782
  @block = block
784
783
  @return_type = return_type
785
- @location = location
786
- @method_def = method_def
784
+ @method_decls = method_decls
787
785
  end
788
786
 
789
787
  def ==(other)
@@ -791,9 +789,7 @@ module Steep
791
789
  other.type_params == type_params &&
792
790
  other.params == params &&
793
791
  other.block == block &&
794
- other.return_type == return_type &&
795
- (!other.method_def || !method_def || other.method_def == method_def) &&
796
- (!other.location || !location || other.location == location)
792
+ other.return_type == return_type
797
793
  end
798
794
 
799
795
  alias eql? ==
@@ -824,8 +820,7 @@ module Steep
824
820
  params: params.subst(s_),
825
821
  block: block&.subst(s_),
826
822
  return_type: return_type.subst(s_),
827
- method_def: method_def,
828
- location: location
823
+ method_decls: method_decls
829
824
  )
830
825
  end
831
826
 
@@ -847,17 +842,15 @@ module Steep
847
842
  params: params.subst(s),
848
843
  block: block&.subst(s),
849
844
  return_type: return_type.subst(s),
850
- location: location,
851
- method_def: method_def)
845
+ method_decls: method_decls)
852
846
  end
853
847
 
854
- def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, location: self.location, method_def: self.method_def)
848
+ def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, method_decls: self.method_decls)
855
849
  self.class.new(type_params: type_params,
856
850
  params: params,
857
851
  block: block,
858
852
  return_type: return_type,
859
- method_def: method_def,
860
- location: location)
853
+ method_decls: method_decls)
861
854
  end
862
855
 
863
856
  def to_s
@@ -873,8 +866,7 @@ module Steep
873
866
  params: params.map_type(&block),
874
867
  block: self.block&.yield_self {|blk| blk.map_type(&block) },
875
868
  return_type: yield(return_type),
876
- location: location,
877
- method_def: method_def)
869
+ method_decls: method_decls)
878
870
  end
879
871
 
880
872
  # Returns a new method type which can be used for the method implementation type of both `self` and `other`.
@@ -902,8 +894,7 @@ module Steep
902
894
  return_type: AST::Types::Union.build(
903
895
  types: [return_type.subst(s1),other.return_type.subst(s2)]
904
896
  ),
905
- method_def: method_def,
906
- location: nil
897
+ method_decls: method_decls + other.method_decls
907
898
  )
908
899
  end
909
900
 
@@ -958,8 +949,7 @@ module Steep
958
949
  block: block,
959
950
  return_type: return_type,
960
951
  type_params: type_params,
961
- method_def: nil,
962
- location: nil
952
+ method_decls: method_decls + other.method_decls
963
953
  )
964
954
  end
965
955
 
@@ -1006,8 +996,7 @@ module Steep
1006
996
  block: block,
1007
997
  return_type: return_type,
1008
998
  type_params: type_params,
1009
- method_def: nil,
1010
- location: nil
999
+ method_decls: method_decls + other.method_decls
1011
1000
  )
1012
1001
  end
1013
1002
  end
@@ -0,0 +1,28 @@
1
+ module Steep
2
+ InstanceMethodName = Struct.new(:type_name, :method_name, keyword_init: true) do
3
+ def to_s
4
+ "#{type_name}##{method_name}"
5
+ end
6
+ end
7
+
8
+ SingletonMethodName = Struct.new(:type_name, :method_name, keyword_init: true) do
9
+ def to_s
10
+ "#{type_name}.#{method_name}"
11
+ end
12
+ end
13
+
14
+ module ::Kernel
15
+ def MethodName(string)
16
+ case string
17
+ when /#/
18
+ type_name, method_name = string.split(/#/, 2)
19
+ InstanceMethodName.new(type_name: TypeName(type_name), method_name: method_name.to_sym)
20
+ when /\./
21
+ type_name, method_name = string.split(/\./, 2)
22
+ SingletonMethodName.new(type_name: TypeName(type_name), method_name: method_name.to_sym)
23
+ else
24
+ raise "Unexpected method name: #{string}"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -10,9 +10,27 @@ module Steep
10
10
 
11
11
  InstanceVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
12
12
  LocalVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
13
- MethodNameItem = Struct.new(:identifier, :range, :method_def, :method_type, :inherited_method, keyword_init: true) do
13
+ MethodNameItem = Struct.new(:identifier, :range, :receiver_type, :method_type, :method_decls, keyword_init: true) do
14
14
  def comment
15
- method_def&.comment
15
+ case method_decls.size
16
+ when 0
17
+ nil
18
+ when 1
19
+ method_decls.to_a.first.method_def&.comment
20
+ else
21
+ nil
22
+ end
23
+ end
24
+
25
+ def inherited?
26
+ case receiver_type
27
+ when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
28
+ method_decls.any? do |decl|
29
+ decl.method_name.type_name != receiver_type.name
30
+ end
31
+ else
32
+ false
33
+ end
16
34
  end
17
35
  end
18
36
 
@@ -245,15 +263,15 @@ module Steep
245
263
  items << MethodNameItem.new(
246
264
  identifier: name,
247
265
  range: range,
248
- method_def: method_type.method_def,
249
- method_type: method_type.method_def&.type || subtyping.factory.method_type_1(method_type, self_type: type),
250
- inherited_method: inherited_method?(method_type.method_def, type)
266
+ receiver_type: type,
267
+ method_type: subtyping.factory.method_type_1(method_type, self_type: type),
268
+ method_decls: method_type.method_decls
251
269
  )
252
270
  end
253
271
  end
254
272
  end
255
273
  end
256
- rescue
274
+ rescue RuntimeError => exn
257
275
  # nop
258
276
  end
259
277
 
@@ -298,15 +316,6 @@ module Steep
298
316
  index
299
317
  end
300
318
 
301
- def inherited_method?(method_def, type)
302
- case type
303
- when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
304
- method_def.implemented_in != type.name
305
- else
306
- false
307
- end
308
- end
309
-
310
319
  def disallowed_method?(name)
311
320
  # initialize isn't invoked by developers when creating
312
321
  # instances of new classes, so don't show it as
@@ -66,7 +66,8 @@ module Steep
66
66
  break_context: nil,
67
67
  self_type: AST::Builtin::Object.instance_type,
68
68
  type_env: type_env,
69
- lvar_env: lvar_env
69
+ lvar_env: lvar_env,
70
+ call_context: TypeInference::MethodCall::TopLevelContext.new
70
71
  )
71
72
 
72
73
  typing = Typing.new(source: source, root_context: context)
@@ -196,7 +196,7 @@ HOVER
196
196
  ),
197
197
  documentation: item.comment&.string,
198
198
  insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
199
- sort_text: item.inherited_method ? 'z' : 'a' # Ensure language server puts non-inherited methods before inherited methods
199
+ sort_text: item.inherited? ? 'z' : 'a' # Ensure language server puts non-inherited methods before inherited methods
200
200
  )
201
201
  when Project::CompletionProvider::InstanceVariableItem
202
202
  label = "#{item.identifier}: #{item.type}"
@@ -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,222 @@ 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]}
2381
-
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)
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
+ )
2386
2425
 
2387
- for_block.typing.add_context_for_body(node, context: for_block.context)
2426
+ constr = synthesize_children(node, skips: [receiver])
2427
+ if block_params
2428
+ block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2388
2429
 
2389
- for_block.synthesize(block_body)
2430
+ constr.type_block_without_hint(
2431
+ node: node,
2432
+ block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
2433
+ block_annotations: block_annotations,
2434
+ block_body: block_body
2435
+ ) do |error|
2436
+ errors << error
2437
+ end
2390
2438
  end
2391
2439
  end
2440
+
2441
+ constr.add_call(call)
2392
2442
  else
2393
- Pair.new(type: type, constr: constr)
2443
+ add_call(
2444
+ TypeInference::MethodCall::NoMethodError.new(
2445
+ node: node,
2446
+ context: context.method_context,
2447
+ method_name: method_name,
2448
+ receiver_type: receiver_type,
2449
+ error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2450
+ )
2451
+ )
2394
2452
  end
2395
2453
  end
2396
2454
 
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
2455
+ def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2456
+ receiver, method_name, *arguments = send_node.children
2457
+ recv_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2406
2458
 
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
- )
2459
+ if unwrap
2460
+ recv_type = unwrap(recv_type)
2412
2461
  end
2413
2462
 
2414
- lvar_env = context.lvar_env.pin_assignments.annotate(block_annotations)
2463
+ receiver_type = checker.factory.deep_expand_alias(recv_type)
2415
2464
 
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}")
2465
+ type, constr = case receiver_type
2466
+ when nil
2467
+ raise
2422
2468
 
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} }")
2469
+ when AST::Types::Any
2470
+ constr = constr.synthesize_children(node, skips: [receiver])
2471
+ constr.add_call(
2472
+ TypeInference::MethodCall::Untyped.new(
2473
+ node: node,
2474
+ context: context.method_context,
2475
+ method_name: method_name
2476
+ )
2477
+ )
2425
2478
 
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} }")
2479
+ when AST::Types::Void, AST::Types::Bot, AST::Types::Top, AST::Types::Var
2480
+ constr = constr.synthesize_children(node, skips: [receiver])
2481
+ constr.add_call(
2482
+ TypeInference::MethodCall::NoMethodError.new(
2483
+ node: node,
2484
+ context: context.method_context,
2485
+ method_name: method_name,
2486
+ receiver_type: receiver_type,
2487
+ error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2488
+ )
2489
+ )
2431
2490
 
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
2491
+ when AST::Types::Self
2492
+ expanded_self = expand_self(receiver_type)
2493
+
2494
+ if expanded_self.is_a?(AST::Types::Self)
2495
+ Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
2496
+
2497
+ constr = constr.synthesize_children(node, skips: [receiver])
2498
+ constr.add_call(
2499
+ TypeInference::MethodCall::NoMethodError.new(
2500
+ node: node,
2501
+ context: context.method_context,
2502
+ method_name: method_name,
2503
+ receiver_type: receiver_type,
2504
+ error: Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2505
+ )
2506
+ )
2507
+ else
2508
+ interface = checker.factory.interface(expanded_self,
2509
+ private: !receiver,
2510
+ self_type: AST::Types::Self.new)
2511
+
2512
+ constr.type_send_interface(node,
2513
+ interface: interface,
2514
+ receiver: receiver,
2515
+ receiver_type: expanded_self,
2516
+ method_name: method_name,
2517
+ arguments: arguments,
2518
+ block_params: block_params,
2519
+ block_body: block_body)
2520
+ end
2521
+ else
2522
+ interface = checker.factory.interface(receiver_type,
2523
+ private: !receiver,
2524
+ self_type: receiver_type)
2525
+
2526
+ constr.type_send_interface(node,
2527
+ interface: interface,
2528
+ receiver: receiver,
2529
+ receiver_type: receiver_type,
2530
+ method_name: method_name,
2531
+ arguments: arguments,
2532
+ block_params: block_params,
2533
+ block_body: block_body)
2534
+ end
2535
+
2536
+ Pair.new(type: type, constr: constr)
2537
+ rescue => exn
2538
+ case exn
2539
+ when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2540
+ # ignore known RBS errors.
2541
+ else
2542
+ Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2543
+ end
2544
+
2545
+ error = Errors::UnexpectedError.new(node: node, error: exn)
2546
+
2547
+ type_any_rec(node)
2548
+
2549
+ add_call(
2550
+ TypeInference::MethodCall::Error.new(
2551
+ node: node,
2552
+ context: context.method_context,
2553
+ method_name: method_name,
2554
+ receiver_type: receiver_type,
2555
+ errors: [error]
2445
2556
  )
2446
- ), return_type]
2557
+ )
2447
2558
  end
2448
2559
 
2449
2560
  def expand_self(type)
@@ -2463,63 +2574,54 @@ module Steep
2463
2574
 
2464
2575
  zips.map do |arg_pairs|
2465
2576
  typing.new_child(node_range) do |child_typing|
2466
- ret = self.with_new_typing(child_typing).try_method_type(
2577
+ self.with_new_typing(child_typing).try_method_type(
2467
2578
  node,
2468
2579
  receiver_type: receiver_type,
2580
+ method_name: method_name,
2469
2581
  method_type: method_type,
2470
2582
  args: args,
2471
2583
  arg_pairs: arg_pairs,
2472
2584
  block_params: block_params,
2473
2585
  block_body: block_body,
2474
- child_typing: child_typing,
2475
2586
  topdown_hint: topdown_hint
2476
2587
  )
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
2588
  end
2484
2589
  end
2485
2590
  end
2486
2591
  end
2487
2592
 
2488
- unless results.empty?
2489
- result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2490
- else
2593
+ case
2594
+ when results.empty?
2491
2595
  method_type = method.method_types.last
2596
+ all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
2597
+ set.merge(method_type.method_decls)
2598
+ end
2599
+ error = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
2600
+ call = TypeInference::MethodCall::Error.new(
2601
+ node: node,
2602
+ context: context.method_context,
2603
+ method_name: method_name,
2604
+ receiver_type: receiver_type,
2605
+ return_type: method_type.return_type,
2606
+ errors: [error],
2607
+ method_decls: all_decls
2608
+ )
2492
2609
  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
2610
+ when (call, constr = results.find {|call, _| call.is_a?(TypeInference::MethodCall::Typed) })
2611
+ # Nop
2612
+ else
2613
+ if results.one?
2614
+ call, constr = results[0]
2507
2615
  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
2616
+ return
2513
2617
  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
2618
  end
2619
+ constr.typing.save!
2620
+
2621
+ [
2622
+ call,
2623
+ update_lvar_env { constr.context.lvar_env }
2624
+ ]
2523
2625
  end
2524
2626
 
2525
2627
  def check_keyword_arg(receiver_type:, node:, method_type:, constraints:)
@@ -2621,14 +2723,12 @@ module Steep
2621
2723
 
2622
2724
  hash_type = AST::Builtin::Hash.instance_type(
2623
2725
  AST::Builtin::Symbol.instance_type,
2624
- AST::Types::Union.build(types: value_types,
2625
- location: method_type.location)
2726
+ AST::Types::Union.build(types: value_types)
2626
2727
  )
2627
2728
  else
2628
2729
  hash_elements = params.required_keywords.merge(
2629
2730
  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)
2731
+ AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
2632
2732
  end
2633
2733
  )
2634
2734
 
@@ -2650,151 +2750,211 @@ module Steep
2650
2750
  nil
2651
2751
  end
2652
2752
 
2653
- def try_method_type(node, receiver_type:, method_type:, args:, arg_pairs:, block_params:, block_body:, child_typing:, topdown_hint:)
2753
+ def try_method_type(node, receiver_type:, method_name:, method_type:, args:, arg_pairs:, block_params:, block_body:, topdown_hint:)
2654
2754
  fresh_types = method_type.type_params.map {|x| AST::Types::Var.fresh(x)}
2655
2755
  fresh_vars = Set.new(fresh_types.map(&:name))
2656
2756
  instantiation = Interface::Substitution.build(method_type.type_params, fresh_types)
2657
2757
 
2658
- construction = self.class.new(
2659
- checker: checker,
2660
- source: source,
2661
- annotations: annotations,
2662
- typing: child_typing,
2663
- context: context
2664
- )
2758
+ constr = self
2665
2759
 
2666
- constr = construction
2760
+ method_type = method_type.instantiate(instantiation)
2667
2761
 
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)
2762
+ constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
2763
+ variance = Subtyping::VariableVariance.from_method_type(method_type)
2764
+ occurence = Subtyping::VariableOccurence.from_method_type(method_type)
2672
2765
 
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)
2766
+ errors = []
2678
2767
 
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
2768
+ arg_pairs.each do |pair|
2769
+ case pair
2770
+ when Array
2771
+ arg_node, param_type = pair
2772
+ param_type = param_type.subst(instantiation)
2684
2773
 
2685
- check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do |result|
2686
- return [Errors::ArgumentTypeMismatch.new(node: arg_node,
2774
+ arg_type, constr = if arg_node.type == :splat
2775
+ constr.synthesize(arg_node.children[0])
2776
+ else
2777
+ constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
2778
+ end
2779
+
2780
+ check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do
2781
+ errors << Errors::ArgumentTypeMismatch.new(node: arg_node,
2687
2782
  receiver_type: receiver_type,
2688
2783
  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)
2784
+ actual: arg_type)
2785
+ end
2786
+ else
2787
+ # keyword
2788
+ result = constr.check_keyword_arg(receiver_type: receiver_type,
2789
+ node: pair,
2790
+ method_type: method_type,
2791
+ constraints: constraints)
2698
2792
 
2699
- if result.is_a?(Errors::Base)
2700
- return [result, constr]
2701
- end
2793
+ if result.is_a?(Errors::Base)
2794
+ errors << result
2702
2795
  end
2703
2796
  end
2797
+ end
2704
2798
 
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
- ]
2799
+ if block_params
2800
+ # block is given
2801
+ block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2802
+ block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2803
+
2804
+ if method_type.block
2805
+ pairs = method_type.block && block_params_&.zip(method_type.block.type.params)
2806
+
2807
+ if pairs
2808
+ begin
2809
+ block_constr = constr.for_block(
2810
+ block_params: block_params_,
2811
+ block_param_hint: method_type.block.type.params,
2812
+ block_annotations: block_annotations,
2813
+ node_type_hint: method_type.return_type
2814
+ )
2815
+ block_constr = block_constr.with_new_typing(
2816
+ block_constr.typing.new_child(
2817
+ range: block_constr.typing.block_range(node)
2818
+ )
2819
+ )
2820
+
2821
+ block_constr.typing.add_context_for_body(node, context: block_constr.context)
2822
+
2823
+ pairs.each do |param, type|
2824
+ _, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
2825
+
2826
+ if param.type
2827
+ check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
2828
+ error = Errors::IncompatibleAssignment.new(
2829
+ node: param.node,
2830
+ lhs_type: param.type,
2831
+ rhs_type: type,
2832
+ result: result
2833
+ )
2834
+ errors << error
2835
+ end
2836
+ end
2740
2837
  end
2741
- end
2742
- end
2743
- end
2744
2838
 
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,
2839
+ s = constraints.solution(
2840
+ checker,
2841
+ self_type: self_type,
2842
+ variance: variance,
2843
+ variables: method_type.params.free_variables + method_type.block.type.params.free_variables
2844
+ )
2845
+ method_type = method_type.subst(s)
2846
+ block_constr = block_constr.update_lvar_env {|env| env.subst(s) }
2847
+ if block_body
2848
+ block_body_type = block_constr.synthesize_block(
2849
+ node: node,
2850
+ block_type_hint: method_type.block.type.return_type,
2851
+ block_body: block_body,
2852
+ topdown_hint: topdown_hint
2853
+ ) do |error|
2854
+ errors << error
2855
+ end
2856
+ else
2857
+ block_body_type = AST::Builtin.nil_type
2858
+ end
2859
+
2860
+ result = check_relation(sub_type: block_body_type,
2762
2861
  super_type: method_type.block.type.return_type,
2763
2862
  constraints: constraints)
2764
2863
 
2765
2864
  case result
2766
2865
  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]
2866
+ s = constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)
2867
+ method_type = method_type.subst(s)
2868
+
2869
+ return_type = method_type.return_type
2870
+ if break_type = block_annotations.break_type
2871
+ return_type = union_type(break_type, return_type)
2774
2872
  end
2775
2873
 
2776
2874
  when Subtyping::Result::Failure
2777
- [Errors::BlockTypeMismatch.new(node: node,
2778
- expected: method_type.block.type,
2779
- actual: type,
2780
- result: result),
2781
- constr]
2875
+ block_type = AST::Types::Proc.new(
2876
+ params: method_type.block.type.params || block_params.params_type,
2877
+ return_type: block_body_type
2878
+ )
2879
+ errors << Errors::BlockTypeMismatch.new(node: node,
2880
+ expected: method_type.block.type,
2881
+ actual: block_type,
2882
+ result: result)
2883
+
2884
+ return_type = method_type.return_type
2782
2885
  end
2886
+
2887
+ block_constr.typing.save!
2888
+ rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2889
+ errors << Errors::UnsatisfiableConstraint.new(
2890
+ node: node,
2891
+ method_type: method_type,
2892
+ var: exn.var,
2893
+ sub_type: exn.sub_type,
2894
+ super_type: exn.super_type,
2895
+ result: exn.result
2896
+ )
2897
+
2898
+ constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
2899
+ errors << error
2900
+ end
2901
+
2902
+ s = Interface::Substitution.build(method_type.free_variables,
2903
+ Array.new(method_type.free_variables.size, AST::Builtin.any_type))
2904
+ method_type = method_type.subst(s)
2783
2905
  end
2906
+ else
2907
+ errors << Errors::UnsupportedSyntax.new(
2908
+ node: block_params,
2909
+ message: "Unsupported block params pattern, probably masgn?"
2910
+ )
2911
+
2912
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2913
+ method_type = method_type.subst(s)
2914
+ end
2915
+ else
2916
+ # Block is given but method doesn't accept
2917
+ #
2918
+ constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
2919
+ errors << error
2920
+ end
2784
2921
 
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]
2922
+ errors << Errors::UnexpectedBlockGiven.new(
2923
+ node: node,
2924
+ method_type: method_type
2925
+ )
2926
+ end
2927
+ else
2928
+ # block is not given
2929
+ if (!method_type.block || method_type.block.optional?)
2930
+ # Method call without block is allowed
2931
+ unless args.block_pass_arg
2932
+ # OK, without block
2933
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2934
+ method_type = method_type.subst(s)
2935
+ else
2936
+ # &block arg is given
2937
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2938
+ method_type = method_type.subst(s)
2939
+
2940
+ errors << Errors::UnexpectedBlockGiven.new(
2941
+ node: node,
2942
+ method_type: method_type
2943
+ )
2793
2944
  end
2945
+ else
2946
+ unless args.block_pass_arg
2947
+ # Required block is missing
2948
+ errors << Errors::RequiredBlockMissing.new(
2949
+ node: node,
2950
+ method_type: method_type
2951
+ )
2794
2952
 
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|
2953
+ s = constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)
2954
+ method_type = method_type.subst(s)
2955
+ else
2956
+ begin
2957
+ method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params))
2798
2958
  block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
2799
2959
  result = check_relation(
2800
2960
  sub_type: block_type,
@@ -2808,68 +2968,65 @@ module Steep
2808
2968
  constraints: constraints
2809
2969
  )
2810
2970
 
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
- ]
2971
+ result.else do |result|
2972
+ errors << Errors::BlockTypeMismatch.new(node: node,
2973
+ expected: method_type.block.type,
2974
+ actual: block_type,
2975
+ result: result)
2826
2976
  end
2977
+
2978
+ method_type = method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: method_type.free_variables))
2827
2979
  end
2980
+ end
2981
+ end
2982
+ end
2828
2983
 
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
- ]
2984
+ call = if errors.empty?
2985
+ TypeInference::MethodCall::Typed.new(
2986
+ node: node,
2987
+ context: context.method_context,
2988
+ receiver_type: receiver_type,
2989
+ method_name: method_name,
2990
+ actual_method_type: method_type,
2991
+ return_type: return_type || method_type.return_type,
2992
+ method_decls: method_type.method_decls
2993
+ )
2994
+ else
2995
+ TypeInference::MethodCall::Error.new(
2996
+ node: node,
2997
+ context: context.method_context,
2998
+ receiver_type: receiver_type,
2999
+ method_name: method_name,
3000
+ return_type: return_type || method_type.return_type,
3001
+ method_decls: method_type.method_decls,
3002
+ errors: errors
3003
+ )
3004
+ end
3005
+
3006
+ [
3007
+ call,
3008
+ constr
3009
+ ]
3010
+ end
3011
+
3012
+ def type_block_without_hint(node:, block_annotations:, block_params:, block_body:, &block)
3013
+ block_constr = for_block(
3014
+ block_params: block_params,
3015
+ block_param_hint: nil,
3016
+ block_annotations: block_annotations,
3017
+ node_type_hint: nil
3018
+ )
2856
3019
 
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
- ]
3020
+ block_constr.typing.add_context_for_body(node, context: block_constr.context)
2865
3021
 
2866
- else
2867
- raise "Unexpected case condition"
2868
- end
3022
+ block_params.params.each do |param|
3023
+ _, block_constr = block_constr.synthesize(param.node, hint: param.type)
2869
3024
  end
3025
+
3026
+ block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body, topdown_hint: false, &block)
2870
3027
  end
2871
3028
 
2872
- def type_block(node:, block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
3029
+ def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
2873
3030
  block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
2874
3031
 
2875
3032
  param_types_hash = {}
@@ -2885,30 +3042,30 @@ module Steep
2885
3042
  end
2886
3043
  end
2887
3044
 
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)
3045
+ decls = param_types_hash.each.with_object({}) do |(name, type), hash|
3046
+ hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
3047
+ end
3048
+ lvar_env = context.lvar_env
3049
+ .pin_assignments
3050
+ .except(decls.keys)
3051
+ .update(assigned_types: decls)
3052
+ .annotate(block_annotations)
2894
3053
 
2895
3054
  break_type = if block_annotations.break_type
2896
3055
  union_type(node_type_hint, block_annotations.break_type)
2897
3056
  else
2898
3057
  node_type_hint
2899
3058
  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
3059
 
3060
+ block_context = TypeInference::Context::BlockContext.new(
3061
+ body_type: block_annotations.block_type
3062
+ )
2905
3063
  break_context = TypeInference::Context::BreakContext.new(
2906
3064
  break_type: break_type,
2907
3065
  next_type: block_context.body_type
2908
3066
  )
2909
- Steep.logger.debug("break_context { type: #{break_context.break_type} }")
2910
3067
 
2911
- for_block_body = self.class.new(
3068
+ self.class.new(
2912
3069
  checker: checker,
2913
3070
  source: source,
2914
3071
  annotations: annotations.merge_block_annotations(block_annotations),
@@ -2920,37 +3077,34 @@ module Steep
2920
3077
  break_context: break_context,
2921
3078
  self_type: block_annotations.self_type || self_type,
2922
3079
  type_env: type_env.dup,
2923
- lvar_env: lvar_env
3080
+ lvar_env: lvar_env,
3081
+ call_context: self.context.call_context
2924
3082
  )
2925
3083
  )
3084
+ end
2926
3085
 
2927
- for_block_body.typing.add_context_for_body(node, context: for_block_body.context)
2928
-
3086
+ def synthesize_block(node:, block_type_hint:, block_body:, topdown_hint:)
2929
3087
  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
3088
+ body_type, _, context =
3089
+ if (body_type = block_context.body_type)
3090
+ check(block_body, body_type) do |expected, actual, result|
3091
+ error = Errors::BlockTypeMismatch.new(node: block_body,
3092
+ expected: expected,
3093
+ actual: actual,
3094
+ result: result)
3095
+ yield(error) if block_given?
3096
+ end
3097
+ else
3098
+ synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
3099
+ end
2941
3100
 
2942
3101
  range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
2943
- typing.add_context(range, context: body_pair.context)
3102
+ typing.add_context(range, context: context)
3103
+
3104
+ body_type
2944
3105
  else
2945
- body_pair = Pair.new(type: AST::Builtin.nil_type, constr: for_block_body)
3106
+ AST::Builtin.nil_type
2946
3107
  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
3108
  end
2955
3109
 
2956
3110
  def each_child_node(node)
@@ -3172,6 +3326,14 @@ module Steep
3172
3326
  !nodes.empty? && nodes.all? {|child| child.type == :class || child.type == :module}
3173
3327
  end
3174
3328
 
3329
+ def type_any_rec(node)
3330
+ add_typing node, type: AST::Builtin.any_type
3331
+
3332
+ each_child_node(node) do |child|
3333
+ type_any_rec(child)
3334
+ end
3335
+ end
3336
+
3175
3337
  def fallback_any_rec(node)
3176
3338
  fallback_to_any(node) unless typing.has_type?(node)
3177
3339