steep 0.33.0 → 0.34.0

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