steep 0.24.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/bin/smoke_runner.rb +3 -4
  4. data/lib/steep.rb +6 -4
  5. data/lib/steep/annotation_parser.rb +2 -4
  6. data/lib/steep/ast/builtin.rb +11 -21
  7. data/lib/steep/ast/types.rb +5 -3
  8. data/lib/steep/ast/types/any.rb +1 -3
  9. data/lib/steep/ast/types/boolean.rb +1 -3
  10. data/lib/steep/ast/types/bot.rb +1 -3
  11. data/lib/steep/ast/types/class.rb +2 -2
  12. data/lib/steep/ast/types/factory.rb +251 -89
  13. data/lib/steep/ast/types/helper.rb +6 -0
  14. data/lib/steep/ast/types/instance.rb +2 -2
  15. data/lib/steep/ast/types/intersection.rb +20 -13
  16. data/lib/steep/ast/types/literal.rb +1 -3
  17. data/lib/steep/ast/types/logic.rb +63 -0
  18. data/lib/steep/ast/types/name.rb +15 -67
  19. data/lib/steep/ast/types/nil.rb +1 -3
  20. data/lib/steep/ast/types/proc.rb +5 -2
  21. data/lib/steep/ast/types/record.rb +9 -4
  22. data/lib/steep/ast/types/self.rb +1 -1
  23. data/lib/steep/ast/types/top.rb +1 -3
  24. data/lib/steep/ast/types/tuple.rb +5 -3
  25. data/lib/steep/ast/types/union.rb +16 -9
  26. data/lib/steep/ast/types/var.rb +2 -2
  27. data/lib/steep/ast/types/void.rb +1 -3
  28. data/lib/steep/drivers/check.rb +4 -0
  29. data/lib/steep/errors.rb +14 -0
  30. data/lib/steep/interface/interface.rb +5 -62
  31. data/lib/steep/interface/method_type.rb +394 -93
  32. data/lib/steep/interface/substitution.rb +48 -6
  33. data/lib/steep/module_helper.rb +25 -0
  34. data/lib/steep/project.rb +25 -0
  35. data/lib/steep/project/completion_provider.rb +48 -51
  36. data/lib/steep/project/file_loader.rb +7 -2
  37. data/lib/steep/project/hover_content.rb +4 -6
  38. data/lib/steep/project/signature_file.rb +33 -0
  39. data/lib/steep/project/{file.rb → source_file.rb} +24 -54
  40. data/lib/steep/project/target.rb +36 -14
  41. data/lib/steep/server/base_worker.rb +5 -3
  42. data/lib/steep/server/code_worker.rb +31 -45
  43. data/lib/steep/server/master.rb +23 -31
  44. data/lib/steep/server/utils.rb +46 -13
  45. data/lib/steep/server/worker_process.rb +4 -2
  46. data/lib/steep/signature/validator.rb +3 -3
  47. data/lib/steep/source.rb +4 -3
  48. data/lib/steep/subtyping/check.rb +46 -59
  49. data/lib/steep/subtyping/constraints.rb +8 -0
  50. data/lib/steep/type_construction.rb +771 -513
  51. data/lib/steep/type_inference/block_params.rb +5 -0
  52. data/lib/steep/type_inference/constant_env.rb +3 -6
  53. data/lib/steep/type_inference/context.rb +8 -0
  54. data/lib/steep/type_inference/context_array.rb +4 -3
  55. data/lib/steep/type_inference/logic.rb +31 -0
  56. data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
  57. data/lib/steep/type_inference/type_env.rb +2 -2
  58. data/lib/steep/typing.rb +7 -0
  59. data/lib/steep/version.rb +1 -1
  60. data/smoke/alias/a.rb +1 -1
  61. data/smoke/case/a.rb +1 -1
  62. data/smoke/hash/d.rb +1 -1
  63. data/smoke/if/a.rb +1 -1
  64. data/smoke/module/a.rb +1 -1
  65. data/smoke/rescue/a.rb +4 -13
  66. data/smoke/toplevel/Steepfile +5 -0
  67. data/smoke/toplevel/a.rb +4 -0
  68. data/smoke/toplevel/a.rbs +3 -0
  69. data/smoke/type_case/a.rb +0 -7
  70. data/steep.gemspec +2 -2
  71. metadata +15 -11
  72. data/lib/steep/ast/method_type.rb +0 -126
  73. data/lib/steep/ast/namespace.rb +0 -80
  74. data/lib/steep/names.rb +0 -86
@@ -5,13 +5,15 @@ module Steep
5
5
  attr_reader :writer
6
6
  attr_reader :stderr
7
7
 
8
+ attr_reader :name
8
9
  attr_reader :wait_thread
9
10
 
10
- def initialize(reader:, writer:, stderr:, wait_thread:)
11
+ def initialize(reader:, writer:, stderr:, wait_thread:, name:)
11
12
  @reader = reader
12
13
  @writer = writer
13
14
  @stderr = stderr
14
15
  @wait_thread = wait_thread
16
+ @name = name
15
17
  end
16
18
 
17
19
  def self.spawn_worker(type, name:, steepfile:)
@@ -33,7 +35,7 @@ module Steep
33
35
  writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
34
36
  reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout)
35
37
 
36
- new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread)
38
+ new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name)
37
39
  end
38
40
 
39
41
  def self.spawn_code_workers(steepfile:, count: [Etc.nprocessors-3, 1].max)
@@ -130,19 +130,19 @@ module Steep
130
130
  yield
131
131
  rescue RBS::InvalidTypeApplicationError => exn
132
132
  @errors << Errors::InvalidTypeApplicationError.new(
133
- name: factory.type_name(exn.type_name),
133
+ name: exn.type_name,
134
134
  args: exn.args.map {|ty| factory.type(ty) },
135
135
  params: exn.params,
136
136
  location: exn.location
137
137
  )
138
138
  rescue RBS::NoTypeFoundError, RBS::NoSuperclassFoundError, RBS::NoMixinFoundError => exn
139
139
  @errors << Errors::UnknownTypeNameError.new(
140
- name: factory.type_name(exn.type_name),
140
+ name: exn.type_name,
141
141
  location: exn.location
142
142
  )
143
143
  rescue RBS::InvalidOverloadMethodError => exn
144
144
  @errors << Errors::InvalidMethodOverloadError.new(
145
- class_name: factory.type_name(exn.type_name),
145
+ class_name: exn.type_name,
146
146
  method_name: exn.method_name,
147
147
  location: exn.members[0].location
148
148
  )
@@ -38,7 +38,7 @@ module Steep
38
38
  end
39
39
 
40
40
  def self.parser
41
- ::Parser::Ruby25.new(Builder.new).tap do |parser|
41
+ ::Parser::Ruby27.new(Builder.new).tap do |parser|
42
42
  parser.diagnostics.all_errors_are_fatal = true
43
43
  parser.diagnostics.ignore_warnings = true
44
44
  end
@@ -60,7 +60,7 @@ module Steep
60
60
  _, comments, _ = yield_self do
61
61
  buffer = ::Parser::Source::Buffer.new(path.to_s)
62
62
  buffer.source = source_code
63
- parser = ::Parser::Ruby25.new
63
+ parser = ::Parser::Ruby27.new
64
64
 
65
65
  parser.tokenize(buffer)
66
66
  end
@@ -79,6 +79,7 @@ module Steep
79
79
  end
80
80
 
81
81
  mapping = {}
82
+
82
83
  construct_mapping(node: node, annotations: annotations, mapping: mapping)
83
84
 
84
85
  annotations.each do |annot|
@@ -185,7 +186,7 @@ module Steep
185
186
  construct_mapping(node: node.children[0], annotations: annotations, mapping: mapping, line_range: nil)
186
187
  end
187
188
 
188
- if node.loc.else
189
+ if node.children.last
189
190
  else_node = node.children.last
190
191
  else_start = node.loc.else.last_line
191
192
  else_end = node.loc.end.line
@@ -10,8 +10,7 @@ module Steep
10
10
  end
11
11
 
12
12
  def instance_super_types(type_name, args:)
13
- type_name_1 = factory.type_name_1(type_name)
14
- ancestors = factory.definition_builder.one_instance_ancestors(type_name_1)
13
+ ancestors = factory.definition_builder.one_instance_ancestors(type_name)
15
14
 
16
15
  subst = unless args.empty?
17
16
  args_ = args.map {|type| factory.type_1(type) }
@@ -19,7 +18,7 @@ module Steep
19
18
  end
20
19
 
21
20
  ancestors.each_ancestor.map do |ancestor|
22
- name = factory.type_name(ancestor.name)
21
+ name = ancestor.name
23
22
 
24
23
  case ancestor
25
24
  when RBS::Definition::Ancestor::Instance
@@ -42,9 +41,8 @@ module Steep
42
41
  )
43
42
  end
44
43
  when RBS::Definition::Ancestor::Singleton
45
- AST::Types::Name::Class.new(
44
+ AST::Types::Name::Singleton.new(
46
45
  name: name,
47
- constructor: nil,
48
46
  location: nil
49
47
  )
50
48
  end
@@ -52,11 +50,10 @@ module Steep
52
50
  end
53
51
 
54
52
  def singleton_super_types(type_name)
55
- type_name_1 = factory.type_name_1(type_name)
56
- ancestors = factory.definition_builder.one_singleton_ancestors(type_name_1)
53
+ ancestors = factory.definition_builder.one_singleton_ancestors(type_name)
57
54
 
58
55
  ancestors.each_ancestor.map do |ancestor|
59
- name = factory.type_name(ancestor.name)
56
+ name = ancestor.name
60
57
 
61
58
  case ancestor
62
59
  when RBS::Definition::Ancestor::Instance
@@ -78,9 +75,8 @@ module Steep
78
75
  )
79
76
  end
80
77
  when RBS::Definition::Ancestor::Singleton
81
- AST::Types::Name::Class.new(
78
+ AST::Types::Name::Singleton.new(
82
79
  name: name,
83
- constructor: nil,
84
80
  location: nil
85
81
  )
86
82
  end
@@ -180,6 +176,14 @@ module Steep
180
176
  constraints: constraints
181
177
  )
182
178
 
179
+ when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
180
+ constraints.add(relation.super_type.name, sub_type: relation.sub_type)
181
+ success(constraints: constraints)
182
+
183
+ when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
184
+ constraints.add(relation.sub_type.name, super_type: relation.super_type)
185
+ success(constraints: constraints)
186
+
183
187
  when relation.sub_type.is_a?(AST::Types::Union)
184
188
  results = relation.sub_type.types.map do |sub_type|
185
189
  check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
@@ -232,14 +236,6 @@ module Steep
232
236
  results.find(&:failure?)
233
237
  end
234
238
 
235
- when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
236
- constraints.add(relation.super_type.name, sub_type: relation.sub_type)
237
- success(constraints: constraints)
238
-
239
- when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
240
- constraints.add(relation.sub_type.name, super_type: relation.super_type)
241
- success(constraints: constraints)
242
-
243
239
  when relation.super_type.is_a?(AST::Types::Var) || relation.sub_type.is_a?(AST::Types::Var)
244
240
  failure(error: Result::Failure::UnknownPairError.new(relation: relation),
245
241
  trace: trace)
@@ -266,7 +262,7 @@ module Steep
266
262
  possible_sub_types = case relation.sub_type
267
263
  when AST::Types::Name::Instance
268
264
  instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
269
- when AST::Types::Name::Class
265
+ when AST::Types::Name::Singleton
270
266
  singleton_super_types(relation.sub_type.name)
271
267
  else
272
268
  []
@@ -302,10 +298,9 @@ module Steep
302
298
  when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
303
299
  if relation.sub_type.types.size >= relation.super_type.types.size
304
300
  pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
305
- results = pairs.flat_map do |t1, t2|
301
+ results = pairs.map do |t1, t2|
306
302
  relation = Relation.new(sub_type: t1, super_type: t2)
307
- [check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints),
308
- check(relation.flip, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)]
303
+ check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
309
304
  end
310
305
 
311
306
  if results.all?(&:success?)
@@ -318,16 +313,17 @@ module Steep
318
313
  trace: trace)
319
314
  end
320
315
 
321
- when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Name::Base)
322
- tuple_interface = factory.interface(relation.sub_type, private: false)
323
- type_interface = factory.interface(relation.super_type, private: false)
316
+ when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
317
+ tuple_element_type = AST::Types::Union.build(
318
+ types: relation.sub_type.types,
319
+ location: relation.sub_type.location
320
+ )
324
321
 
325
- check_interface(tuple_interface,
326
- type_interface,
327
- self_type: self_type,
328
- assumption: assumption,
329
- trace: trace,
330
- constraints: constraints)
322
+ check(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]),
323
+ self_type: self_type,
324
+ assumption: assumption,
325
+ trace: trace,
326
+ constraints: constraints)
331
327
 
332
328
  when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
333
329
  if Set.new(relation.sub_type.elements.keys).superset?(Set.new(relation.super_type.elements.keys))
@@ -394,12 +390,12 @@ module Steep
394
390
  end
395
391
 
396
392
  def definition_for_type(type)
397
- type_name = factory.type_name_1(type.name)
393
+ type_name = type.name
398
394
 
399
395
  case type
400
396
  when AST::Types::Name::Instance
401
397
  factory.definition_builder.build_instance(type_name)
402
- when AST::Types::Name::Class
398
+ when AST::Types::Name::Singleton
403
399
  factory.definition_builder.build_singleton(type_name)
404
400
  when AST::Types::Name::Interface
405
401
  factory.definition_builder.build_interface(type_name)
@@ -484,11 +480,7 @@ module Steep
484
480
  if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
485
481
  sub_type.args.zip(super_type.args)
486
482
  end
487
- when sub_type.is_a?(AST::Types::Name::Class) && super_type.is_a?(AST::Types::Name::Class)
488
- if sub_type.name == super_type.name
489
- []
490
- end
491
- when sub_type.is_a?(AST::Types::Name::Module) && super_type.is_a?(AST::Types::Name::Module)
483
+ when sub_type.is_a?(AST::Types::Name::Singleton) && super_type.is_a?(AST::Types::Name::Singleton)
492
484
  if sub_type.name == super_type.name
493
485
  []
494
486
  end
@@ -535,29 +527,24 @@ module Steep
535
527
 
536
528
  def check_method(name, sub_method, super_method, self_type:, assumption:, trace:, constraints:)
537
529
  trace.method name, sub_method, super_method do
538
- case
539
- when sub_method.overload? && super_method.overload?
540
- super_method.types.map do |super_type|
541
- sub_method.types.map do |sub_type|
542
- check_generic_method_type name,
543
- sub_type,
544
- super_type,
545
- self_type: self_type,
546
- assumption: assumption,
547
- trace: trace,
548
- constraints: constraints
549
- end.yield_self do |results|
550
- results.find(&:success?) || results[0]
551
- end
530
+ super_method.method_types.map do |super_type|
531
+ sub_method.method_types.map do |sub_type|
532
+ check_generic_method_type name,
533
+ sub_type,
534
+ super_type,
535
+ self_type: self_type,
536
+ assumption: assumption,
537
+ trace: trace,
538
+ constraints: constraints
552
539
  end.yield_self do |results|
553
- if results.all?(&:success?) || sub_method.incompatible?
554
- success constraints: constraints
555
- else
556
- results.select(&:failure?).last
557
- end
540
+ results.find(&:success?) || results[0]
541
+ end
542
+ end.yield_self do |results|
543
+ if results.all?(&:success?)
544
+ success constraints: constraints
545
+ else
546
+ results.select(&:failure?).last
558
547
  end
559
- else
560
- raise "aaaaaaaaaaaaaa"
561
548
  end
562
549
  end
563
550
  end
@@ -104,6 +104,14 @@ module Steep
104
104
  def add(var, sub_type: nil, super_type: nil)
105
105
  subs, supers = dictionary[var]
106
106
 
107
+ if sub_type.is_a?(AST::Types::Logic::Base)
108
+ sub_type = AST::Builtin.bool_type
109
+ end
110
+
111
+ if super_type.is_a?(AST::Types::Logic::Base)
112
+ super_type = AST::Builtin.bool_type
113
+ end
114
+
107
115
  if super_type && !super_type.is_a?(AST::Types::Top)
108
116
  supers << eliminate_variable(super_type, to: AST::Types::Top.new)
109
117
  end
@@ -33,6 +33,8 @@ module Steep
33
33
  end
34
34
  end
35
35
 
36
+ include ModuleHelper
37
+
36
38
  attr_reader :checker
37
39
  attr_reader :source
38
40
  attr_reader :annotations
@@ -113,6 +115,7 @@ module Steep
113
115
  end
114
116
 
115
117
  def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
118
+ Steep.logger.debug { "check_relation: self:#{self_type} |- #{sub_type} <: #{super_type}" }
116
119
  checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
117
120
  end
118
121
 
@@ -168,7 +171,7 @@ module Steep
168
171
 
169
172
  super_method = if definition
170
173
  if (this_method = definition.methods[method_name])
171
- if module_context&.class_name == checker.factory.type_name(this_method.defined_in)
174
+ if module_context&.class_name == this_method.defined_in
172
175
  this_method.super_method
173
176
  else
174
177
  this_method
@@ -253,7 +256,7 @@ module Steep
253
256
  end
254
257
 
255
258
  if name
256
- absolute_name_ = checker.factory.type_name_1(name)
259
+ absolute_name_ = name
257
260
  entry = checker.factory.env.class_decls[absolute_name_]
258
261
  AST::Annotation::Implements::Module.new(
259
262
  name: name,
@@ -264,7 +267,7 @@ module Steep
264
267
  end
265
268
 
266
269
  def for_module(node)
267
- new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
270
+ new_module_name = module_name_from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
268
271
  new_namespace = nested_namespace_for_module(new_module_name)
269
272
 
270
273
  const_context = [new_namespace] + self.module_context.const_env.context
@@ -279,14 +282,13 @@ module Steep
279
282
  module_name = implement_module_name.name
280
283
  module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
281
284
 
282
- type_name_ = checker.factory.type_name_1(implement_module_name.name)
285
+ type_name_ = implement_module_name.name
283
286
  module_entry = checker.factory.definition_builder.env.class_decls[type_name_]
284
287
  instance_def = checker.factory.definition_builder.build_instance(type_name_)
285
288
  module_def = checker.factory.definition_builder.build_singleton(type_name_)
286
289
 
287
290
  instance_type = AST::Types::Intersection.build(
288
291
  types: [
289
- AST::Types::Name::Instance.new(name: module_name, args: module_args),
290
292
  AST::Builtin::Object.instance_type,
291
293
  *module_entry.self_types.map {|module_self|
292
294
  type = case
@@ -304,11 +306,12 @@ module Steep
304
306
  )
305
307
  end
306
308
  checker.factory.type(type)
307
- }
309
+ },
310
+ AST::Types::Name::Instance.new(name: module_name, args: module_args)
308
311
  ].compact
309
312
  )
310
313
 
311
- module_type = AST::Types::Name::Class.new(name: module_name, constructor: nil)
314
+ module_type = AST::Types::Name::Singleton.new(name: module_name)
312
315
  end
313
316
 
314
317
  if annots.instance_type
@@ -358,8 +361,8 @@ module Steep
358
361
  end
359
362
 
360
363
  def for_class(node)
361
- new_class_name = Names::Module.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
362
- super_class_name = node.children[1] && Names::Module.from_node(node.children[1])
364
+ new_class_name = module_name_from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
365
+ super_class_name = node.children[1] && module_name_from_node(node.children[1])
363
366
  new_namespace = nested_namespace_for_module(new_class_name)
364
367
 
365
368
  annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
@@ -374,12 +377,12 @@ module Steep
374
377
  class_name = implement_module_name.name
375
378
  class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
376
379
 
377
- type_name_ = checker.factory.type_name_1(implement_module_name.name)
380
+ type_name_ = implement_module_name.name
378
381
  instance_def = checker.factory.definition_builder.build_instance(type_name_)
379
382
  module_def = checker.factory.definition_builder.build_singleton(type_name_)
380
383
 
381
384
  instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
382
- module_type = AST::Types::Name::Class.new(name: class_name, constructor: nil)
385
+ module_type = AST::Types::Name::Singleton.new(name: class_name)
383
386
  end
384
387
 
385
388
  if annots.instance_type
@@ -443,28 +446,36 @@ module Steep
443
446
  end
444
447
 
445
448
  module_type = case instance_type
446
- when AST::Types::Name::Class
447
- AST::Builtin::Class.instance_type
448
- when AST::Types::Name::Module
449
- AST::Builtin::Module.instance_type
449
+ when AST::Types::Name::Singleton
450
+ type_name = instance_type.name
451
+
452
+ case checker.factory.env.class_decls[type_name]
453
+ when RBS::Environment::ModuleEntry
454
+ AST::Builtin::Module.instance_type
455
+ when RBS::Environment::ClassEntry
456
+ AST::Builtin::Class.instance_type
457
+ else
458
+ raise
459
+ end
460
+
450
461
  when AST::Types::Name::Instance
451
- instance_type.to_class(constructor: nil)
462
+ instance_type.to_module
452
463
  else
453
- raise "Unexpected type for sclass node: #{type}"
464
+ return
454
465
  end
455
466
 
456
467
  instance_definition = case instance_type
457
- when AST::Types::Name::Class, AST::Types::Name::Module
458
- type_name = checker.factory.type_name_1(instance_type.name)
468
+ when AST::Types::Name::Singleton
469
+ type_name = instance_type.name
459
470
  checker.factory.definition_builder.build_singleton(type_name)
460
471
  when AST::Types::Name::Instance
461
- type_name = checker.factory.type_name_1(instance_type.name)
472
+ type_name = instance_type.name
462
473
  checker.factory.definition_builder.build_instance(type_name)
463
474
  end
464
475
 
465
476
  module_definition = case module_type
466
- when AST::Types::Name::Class, AST::Types::Name::Module
467
- type_name = checker.factory.type_name_1(instance_type.name)
477
+ when AST::Types::Name::Singleton
478
+ type_name = instance_type.name
468
479
  checker.factory.definition_builder.build_singleton(type_name)
469
480
  else
470
481
  nil
@@ -638,7 +649,10 @@ module Steep
638
649
  when :__skip__
639
650
  add_typing(node, type: AST::Builtin.any_type)
640
651
  else
641
- hint ||= context.lvar_env.declared_types[name]&.type
652
+ if !hint || hint.is_a?(AST::Types::Void)
653
+ hint = context.lvar_env.declared_types[name]&.type
654
+ end
655
+
642
656
  rhs_result = synthesize(rhs, hint: hint)
643
657
 
644
658
  constr = rhs_result.constr.update_lvar_env do |lvar_env|
@@ -683,8 +697,8 @@ module Steep
683
697
  yield_self do
684
698
  if self_class?(node)
685
699
  module_type = expand_alias(module_context.module_type)
686
- type = if module_type.is_a?(AST::Types::Name::Class)
687
- AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
700
+ type = if module_type.is_a?(AST::Types::Name::Singleton)
701
+ AST::Types::Name::Singleton.new(name: module_type.name)
688
702
  else
689
703
  module_type
690
704
  end
@@ -699,8 +713,8 @@ module Steep
699
713
  yield_self do
700
714
  pair = if self_class?(node)
701
715
  module_type = expand_alias(module_context.module_type)
702
- type = if module_type.is_a?(AST::Types::Name::Class)
703
- AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
716
+ type = if module_type.is_a?(AST::Types::Name::Singleton)
717
+ AST::Types::Name::Singleton.new(name: module_type.name)
704
718
  else
705
719
  module_type
706
720
  end
@@ -744,6 +758,23 @@ module Steep
744
758
 
745
759
  constr.add_typing(node, type: type)
746
760
 
761
+ when :cvasgn
762
+ var_node = lhs.updated(:cvar)
763
+ send_node = rhs.updated(:send, [var_node, op, rhs])
764
+ new_node = node.updated(:cvasgn, [lhs.children[0], send_node])
765
+
766
+ type, constr = synthesize(new_node, hint: hint)
767
+
768
+ constr.add_typing(node, type: type)
769
+
770
+ when :send
771
+ new_rhs = rhs.updated(:send, [lhs, node.children[1], node.children[2]])
772
+ new_node = lhs.updated(:send, [lhs.children[0], :"#{lhs.children[1]}=", *lhs.children.drop(2), new_rhs])
773
+
774
+ type, constr = synthesize(new_node, hint: hint)
775
+
776
+ constr.add_typing(node, type: type)
777
+
747
778
  else
748
779
  Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
749
780
 
@@ -760,11 +791,10 @@ module Steep
760
791
  synthesize(child)
761
792
  end
762
793
 
763
- super_method = Interface::Interface::Combination.overload(
764
- method_context.super_method.method_types.map {|method_type|
794
+ super_method = Interface::Interface::Entry.new(
795
+ method_types: method_context.super_method.method_types.map {|method_type|
765
796
  checker.factory.method_type(method_type, self_type: self_type)
766
- },
767
- incompatible: false
797
+ }
768
798
  )
769
799
  args = TypeInference::SendArgs.from_nodes(node.children.dup)
770
800
 
@@ -811,7 +841,7 @@ module Steep
811
841
  new.typing.add_context_for_body(node, context: new.context)
812
842
 
813
843
  each_child_node(args_node) do |arg|
814
- new.synthesize(arg)
844
+ _, new = new.synthesize(arg)
815
845
  end
816
846
 
817
847
  body_pair = if body_node
@@ -860,10 +890,10 @@ module Steep
860
890
  self_type = expand_self(self_type)
861
891
  definition = case self_type
862
892
  when AST::Types::Name::Instance
863
- name = checker.factory.type_name_1(self_type.name)
893
+ name = self_type.name
864
894
  checker.factory.definition_builder.build_singleton(name)
865
- when AST::Types::Name::Module, AST::Types::Name::Class
866
- name = checker.factory.type_name_1(self_type.name)
895
+ when AST::Types::Name::Singleton
896
+ name = self_type.name
867
897
  checker.factory.definition_builder.build_singleton(name)
868
898
  end
869
899
 
@@ -999,11 +1029,17 @@ module Steep
999
1029
  yield_self do
1000
1030
  var = node.children[0]
1001
1031
  type = context.lvar_env[var.name]
1002
- unless type
1032
+
1033
+ if type
1034
+ add_typing(node, type: type)
1035
+ else
1003
1036
  type = AST::Builtin.any_type
1004
- Steep.logger.error { "Unknown arg type: #{node}" }
1037
+ if context&.method_context&.method_type
1038
+ Steep.logger.error { "Unknown arg type: #{node}" }
1039
+ end
1040
+
1041
+ lvasgn(node, type)
1005
1042
  end
1006
- add_typing(node, type: type)
1007
1043
  end
1008
1044
 
1009
1045
  when :optarg, :kwoptarg
@@ -1011,12 +1047,13 @@ module Steep
1011
1047
  var = node.children[0]
1012
1048
  rhs = node.children[1]
1013
1049
 
1014
- type = context.lvar_env[var.name]
1050
+ var_type = context.lvar_env[var.name]
1051
+ node_type, constr = synthesize(rhs, hint: var_type)
1015
1052
 
1016
- node_type, constr = synthesize(rhs, hint: type)
1053
+ type = AST::Types::Union.build(types: [var_type, node_type])
1017
1054
 
1018
1055
  constr_ = constr.update_lvar_env do |env|
1019
- env.assign(var.name, node: node, type: node_type) do |declared_type, type, result|
1056
+ env.assign(var.name, node: node, type: type) do |declared_type, type, result|
1020
1057
  typing.add_error(
1021
1058
  Errors::IncompatibleAssignment.new(node: node,
1022
1059
  lhs_type: declared_type,
@@ -1026,7 +1063,7 @@ module Steep
1026
1063
  end
1027
1064
  end
1028
1065
 
1029
- add_typing(node, type: constr_.context.lvar_env[var.name], constr: constr_)
1066
+ add_typing(node, type: type, constr: constr_)
1030
1067
  end
1031
1068
 
1032
1069
  when :restarg
@@ -1034,7 +1071,9 @@ module Steep
1034
1071
  var = node.children[0]
1035
1072
  type = context.lvar_env[var.name]
1036
1073
  unless type
1037
- Steep.logger.error { "Unknown variable: #{node}" }
1074
+ if context&.method_context&.method_type
1075
+ Steep.logger.error { "Unknown variable: #{node}" }
1076
+ end
1038
1077
  typing.add_error Errors::FallbackAny.new(node: node)
1039
1078
  type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
1040
1079
  end
@@ -1047,7 +1086,9 @@ module Steep
1047
1086
  var = node.children[0]
1048
1087
  type = context.lvar_env[var.name]
1049
1088
  unless type
1050
- Steep.logger.error { "Unknown variable: #{node}" }
1089
+ if context&.method_context&.method_type
1090
+ Steep.logger.error { "Unknown variable: #{node}" }
1091
+ end
1051
1092
  typing.add_error Errors::FallbackAny.new(node: node)
1052
1093
  type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
1053
1094
  end
@@ -1202,6 +1243,17 @@ module Steep
1202
1243
  type, constr = synthesize(node.children[0])
1203
1244
  constructor = constr.for_sclass(node, type)
1204
1245
 
1246
+ unless constructor
1247
+ typing.add_error(
1248
+ Errors::UnsupportedSyntax.new(
1249
+ node: node,
1250
+ message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
1251
+ )
1252
+ )
1253
+ constr.add_typing(node, type: AST::Builtin.nil_type)
1254
+ return
1255
+ end
1256
+
1205
1257
  constructor.typing.add_context_for_node(node, context: constructor.context)
1206
1258
  constructor.typing.add_context_for_body(node, context: constructor.context)
1207
1259
 
@@ -1213,14 +1265,14 @@ module Steep
1213
1265
  end
1214
1266
  end
1215
1267
 
1216
- add_typing(node, type: AST::Builtin.nil_type)
1268
+ constr.add_typing(node, type: AST::Builtin.nil_type)
1217
1269
  end
1218
1270
 
1219
1271
  when :self
1220
1272
  add_typing node, type: AST::Types::Self.new
1221
1273
 
1222
1274
  when :const
1223
- const_name = Names::Module.from_node(node)
1275
+ const_name = module_name_from_node(node)
1224
1276
 
1225
1277
  if const_name
1226
1278
  type = type_env.get(const: const_name) do
@@ -1233,7 +1285,7 @@ module Steep
1233
1285
 
1234
1286
  when :casgn
1235
1287
  yield_self do
1236
- const_name = Names::Module.from_node(node)
1288
+ const_name = module_name_from_node(node)
1237
1289
  if const_name
1238
1290
  const_type = type_env.get(const: const_name) {}
1239
1291
  value_type = synthesize(node.children.last, hint: const_type).type
@@ -1301,84 +1353,62 @@ module Steep
1301
1353
  when :array
1302
1354
  yield_self do
1303
1355
  if node.children.empty?
1304
- typing.add_error Errors::FallbackAny.new(node: node) unless hint
1305
-
1306
- array_type = if hint
1307
- if check_relation(sub_type: AST::Builtin::Array.instance_type(AST::Builtin.any_type),
1308
- super_type: hint).success?
1309
- hint
1310
- end
1311
- end
1312
-
1313
- add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
1314
- else
1315
- is_tuple = nil
1316
-
1317
- expand_alias(hint) do |hint|
1318
- is_tuple = hint.is_a?(AST::Types::Tuple)
1319
- is_tuple &&= node.children.all? {|child| child.type != :splat}
1320
- is_tuple &&= node.children.size >= hint.types.size
1321
- is_tuple &&= hint.types.map.with_index do |child_type, index|
1322
- child_node = node.children[index]
1323
- [synthesize(child_node, hint: child_type).type, child_type]
1324
- end.all? do |node_type, hint_type|
1325
- result = check_relation(sub_type: node_type, super_type: hint_type)
1326
- result.success?
1356
+ if hint
1357
+ array = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
1358
+ if check_relation(sub_type: array, super_type: hint).success?
1359
+ add_typing node, type: hint
1360
+ else
1361
+ add_typing node, type: array
1327
1362
  end
1328
- end
1329
-
1330
- if is_tuple
1331
- array_type = hint
1332
1363
  else
1333
- element_hint = expand_alias(hint) do |hint|
1334
- AST::Builtin::Array.instance_type?(hint) && hint.args[0]
1364
+ typing.add_error Errors::FallbackAny.new(node: node)
1365
+ add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
1366
+ end
1367
+ else
1368
+ node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
1369
+
1370
+ if hint && !(tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) }).empty?
1371
+ tuples.each do |tuple|
1372
+ typing.new_child(node_range) do |child_typing|
1373
+ pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
1374
+ if pair && pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
1375
+ child_typing.save!
1376
+ return pair.with(constr: pair.constr.with_new_typing(typing))
1377
+ end
1378
+ end
1335
1379
  end
1380
+ end
1336
1381
 
1337
- element_types = node.children.flat_map do |e|
1338
- if e.type == :splat
1339
- Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
1340
- synthesize(e.children.first).type.yield_self do |type|
1341
- expand_alias(type) do |ty|
1342
- case ty
1343
- when AST::Types::Union
1344
- ty.types
1345
- else
1346
- [ty]
1347
- end
1348
- end
1349
- end.map do |type|
1350
- case
1351
- when AST::Builtin::Array.instance_type?(type)
1352
- type.args.first
1353
- when AST::Builtin::Range.instance_type?(type)
1354
- type.args.first
1355
- else
1356
- type
1357
- end
1382
+ if hint && !(arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) }).empty?
1383
+ arrays.each do |array|
1384
+ typing.new_child(node_range) do |child_typing|
1385
+ pair = with_new_typing(child_typing).try_array_type(node, array)
1386
+ if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
1387
+ child_typing.save!
1388
+ return pair.with(constr: pair.constr.with_new_typing(typing))
1358
1389
  end
1359
- else
1360
- [select_super_type(synthesize(e, hint: element_hint).type, element_hint)]
1361
1390
  end
1362
1391
  end
1363
- array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
1364
1392
  end
1365
1393
 
1366
- add_typing(node, type: array_type)
1394
+ try_array_type(node, nil)
1367
1395
  end
1368
1396
  end
1369
1397
 
1370
1398
  when :and
1371
1399
  yield_self do
1372
1400
  left, right = node.children
1373
- logic = TypeInference::Logic.new(subtyping: checker)
1374
- truthy, falsey = logic.nodes(node: left)
1375
1401
 
1376
1402
  left_type, constr = synthesize(left)
1377
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1378
- falsey_vars: falsey.vars,
1379
- lvar_env: constr.context.lvar_env)
1380
1403
 
1381
- right_type, constr = constr.update_lvar_env { truthy_env }.for_branch(right).synthesize(right)
1404
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1405
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
1406
+
1407
+ right_type, constr = constr
1408
+ .update_lvar_env { truthy_env }
1409
+ .tap {|constr| typing.add_context_for_node(right, context: constr.context) }
1410
+ .for_branch(right)
1411
+ .synthesize(right)
1382
1412
 
1383
1413
  type = if left_type.is_a?(AST::Types::Boolean)
1384
1414
  union_type(left_type, right_type)
@@ -1400,16 +1430,18 @@ module Steep
1400
1430
  when :or
1401
1431
  yield_self do
1402
1432
  left, right = node.children
1403
- logic = TypeInference::Logic.new(subtyping: checker)
1404
- truthy, falsey = logic.nodes(node: left)
1405
1433
 
1406
1434
  left_type, constr = synthesize(left, hint: hint)
1407
- truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
1408
- falsey_vars: falsey.vars,
1409
- lvar_env: constr.context.lvar_env)
1410
- left_type_t, _ = logic.partition_union(left_type)
1411
1435
 
1412
- right_type, constr = constr.update_lvar_env { falsey_env }.for_branch(right).synthesize(right, hint: left_type_t)
1436
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1437
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
1438
+
1439
+ left_type_t, _ = checker.factory.unwrap_optional(left_type)
1440
+ right_type, constr = constr
1441
+ .update_lvar_env { falsey_env }
1442
+ .tap {|constr| typing.add_context_for_node(right, context: constr.context) }
1443
+ .for_branch(right)
1444
+ .synthesize(right, hint: left_type_t)
1413
1445
 
1414
1446
  type = union_type(left_type_t, right_type)
1415
1447
 
@@ -1428,12 +1460,8 @@ module Steep
1428
1460
  cond, true_clause, false_clause = node.children
1429
1461
 
1430
1462
  cond_type, constr = synthesize(cond)
1431
- logic = TypeInference::Logic.new(subtyping: checker)
1432
-
1433
- truthys, falseys = logic.nodes(node: cond)
1434
- truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
1435
- falsey_vars: falseys.vars,
1436
- lvar_env: constr.context.lvar_env)
1463
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing)
1464
+ truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: cond_type, node: cond)
1437
1465
 
1438
1466
  if true_clause
1439
1467
  true_pair = constr
@@ -1483,90 +1511,109 @@ module Steep
1483
1511
  cond, *whens, els = node.children
1484
1512
 
1485
1513
  constr = self
1514
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1486
1515
 
1487
1516
  if cond
1488
- cond_type, constr = synthesize(cond)
1489
- cond_type = expand_alias(cond_type)
1490
- if cond_type.is_a?(AST::Types::Union)
1491
- var_names = TypeConstruction.value_variables(cond)
1492
- var_types = cond_type.types.dup
1493
- end
1494
- end
1517
+ branch_pairs = []
1495
1518
 
1496
- branch_pairs = []
1519
+ cond_type, constr = constr.synthesize(cond)
1520
+ _, cond_vars = interpreter.decompose_value(cond)
1497
1521
 
1498
- whens.each do |clause|
1499
- *tests, body = clause.children
1522
+ when_constr = constr
1523
+ whens.each do |clause|
1524
+ *tests, body = clause.children
1500
1525
 
1501
- test_types = []
1502
- clause_constr = constr
1526
+ test_constr = when_constr
1527
+ test_envs = []
1503
1528
 
1504
- tests.each do |test|
1505
- type, clause_constr = synthesize(test)
1506
- test_types << expand_alias(type)
1529
+ tests.each do |test|
1530
+ test_node = test.updated(:send, [test, :===, cond.dup])
1531
+ test_type, test_constr = test_constr.synthesize(test_node)
1532
+ truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
1533
+ test_envs << truthy_env
1534
+ test_constr = test_constr.update_lvar_env { falsy_env }
1535
+ end
1536
+
1537
+ body_constr = when_constr.update_lvar_env {|env| env.except(cond_vars).join(*test_envs) }
1538
+
1539
+ if body
1540
+ branch_pairs << body_constr
1541
+ .for_branch(body)
1542
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1543
+ .synthesize(body, hint: hint)
1544
+ else
1545
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
1546
+ end
1547
+
1548
+ when_constr = test_constr
1507
1549
  end
1508
1550
 
1509
- if body
1510
- if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Class) }
1511
- var_types_in_body = test_types.flat_map do |test_type|
1512
- filtered_types = var_types.select do |var_type|
1513
- var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
1514
- end
1515
- if filtered_types.empty?
1516
- to_instance_type(test_type)
1517
- else
1518
- filtered_types
1519
- end
1520
- end
1551
+ if els
1552
+ begin_pos = node.loc.else.end_pos
1553
+ end_pos = node.loc.end.begin_pos
1554
+ typing.add_context(begin_pos..end_pos, context: when_constr.context)
1521
1555
 
1522
- var_types.reject! do |type|
1523
- var_types_in_body.any? do |test_type|
1524
- type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1525
- end
1526
- end
1556
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1557
+ end
1527
1558
 
1528
- var_type_in_body = union_type(*var_types_in_body)
1529
- type_case_override = var_names.each.with_object({}) do |var_name, hash|
1530
- hash[var_name] = var_type_in_body
1531
- end
1559
+ types = branch_pairs.map(&:type)
1560
+ constrs = branch_pairs.map(&:constr)
1532
1561
 
1533
- branch_pairs << clause_constr
1534
- .for_branch(body, type_case_override: type_case_override)
1535
- .synthesize(body, hint: hint)
1536
- else
1537
- branch_pairs << clause_constr.synthesize(body, hint: hint)
1562
+ unless els
1563
+ constrs << when_constr
1564
+ end
1565
+
1566
+ if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
1567
+ # Exhaustive
1568
+ if els
1569
+ typing.add_error Errors::ElseOnExhaustiveCase.new(node: els, type: cond_type)
1538
1570
  end
1539
1571
  else
1540
- branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1572
+ unless els
1573
+ types << AST::Builtin.nil_type
1574
+ end
1541
1575
  end
1542
- end
1576
+ else
1577
+ branch_pairs = []
1578
+
1579
+ when_constr = constr
1543
1580
 
1544
- if els
1545
- if var_names && var_types
1546
- if var_types.empty?
1547
- typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
1581
+ whens.each do |clause|
1582
+ *tests, body = clause.children
1583
+
1584
+ test_constr = when_constr
1585
+ test_envs = []
1586
+
1587
+ tests.each do |test|
1588
+ test_type, test_constr = test_constr.synthesize(test)
1589
+ truthy_env, falsy_env = interpreter.eval(env: test_constr.context.lvar_env, type: test_type, node: test)
1590
+ test_envs << truthy_env
1591
+ test_constr = test_constr.update_lvar_env { falsy_env }
1548
1592
  end
1549
1593
 
1550
- else_override = var_names.each.with_object({}) do |var_name, hash|
1551
- hash[var_name] = unless var_types.empty?
1552
- union_type(*var_types)
1553
- else
1554
- AST::Builtin.any_type
1555
- end
1594
+ clause_constr = when_constr.update_lvar_env {|env| env.join(*test_envs) }
1595
+ when_constr = test_constr
1596
+
1597
+ if body
1598
+ branch_pairs << clause_constr
1599
+ .for_branch(body)
1600
+ .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
1601
+ .synthesize(body, hint: hint)
1602
+ else
1603
+ branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
1556
1604
  end
1557
- branch_pairs << constr
1558
- .for_branch(els, type_case_override: else_override)
1559
- .synthesize(els, hint: hint)
1560
- else
1561
- branch_pairs << constr.synthesize(els, hint: hint)
1562
1605
  end
1563
- end
1564
1606
 
1565
- types = branch_pairs.map(&:type)
1566
- constrs = branch_pairs.map(&:constr)
1607
+ if els
1608
+ branch_pairs << when_constr.synthesize(els, hint: hint)
1609
+ end
1610
+
1611
+ types = branch_pairs.map(&:type)
1612
+ constrs = branch_pairs.map(&:constr)
1567
1613
 
1568
- unless var_types&.empty? || els
1569
- types.push AST::Builtin.nil_type
1614
+ unless els
1615
+ types << AST::Builtin.nil_type
1616
+ end
1570
1617
  end
1571
1618
 
1572
1619
  constr = constr.update_lvar_env do |env|
@@ -1579,7 +1626,7 @@ module Steep
1579
1626
  when :rescue
1580
1627
  yield_self do
1581
1628
  body, *resbodies, else_node = node.children
1582
- body_pair = synthesize(body) if body
1629
+ body_pair = synthesize(body, hint: hint) if body
1583
1630
 
1584
1631
  body_constr = if body_pair
1585
1632
  self.update_lvar_env do |env|
@@ -1617,7 +1664,7 @@ module Steep
1617
1664
  instance_types = exn_types.map do |type|
1618
1665
  type = expand_alias(type)
1619
1666
  case
1620
- when type.is_a?(AST::Types::Name::Class)
1667
+ when type.is_a?(AST::Types::Name::Singleton)
1621
1668
  to_instance_type(type)
1622
1669
  else
1623
1670
  AST::Builtin.any_type
@@ -1631,7 +1678,7 @@ module Steep
1631
1678
  resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
1632
1679
 
1633
1680
  if body
1634
- resbody_construction.synthesize(body)
1681
+ resbody_construction.synthesize(body, hint: hint)
1635
1682
  else
1636
1683
  Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
1637
1684
  end
@@ -1641,7 +1688,7 @@ module Steep
1641
1688
  resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
1642
1689
 
1643
1690
  if else_node
1644
- else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
1691
+ else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node, hint: hint)
1645
1692
  add_typing(node,
1646
1693
  type: union_type(*[else_pair.type, *resbody_types].compact),
1647
1694
  constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
@@ -1657,7 +1704,7 @@ module Steep
1657
1704
  klasses, asgn, body = node.children
1658
1705
  synthesize(klasses) if klasses
1659
1706
  synthesize(asgn) if asgn
1660
- body_type = synthesize(body).type if body
1707
+ body_type = synthesize(body, hint: hint).type if body
1661
1708
  add_typing(node, type: body_type)
1662
1709
  end
1663
1710
 
@@ -1672,19 +1719,62 @@ module Steep
1672
1719
  when :masgn
1673
1720
  type_masgn(node)
1674
1721
 
1722
+ when :for
1723
+ yield_self do
1724
+ asgn, collection, body = node.children
1725
+
1726
+ collection_type, constr = synthesize(collection)
1727
+ collection_type = expand_self(collection_type)
1728
+
1729
+ var_type = case collection_type
1730
+ when AST::Types::Any
1731
+ AST::Types::Any.new
1732
+ else
1733
+ each = checker.factory.interface(collection_type, private: true).methods[:each]
1734
+ method_type = (each&.method_types || []).find {|type| type.block && type.block.type.params.first_param }
1735
+ method_type&.yield_self do |method_type|
1736
+ method_type.block.type.params.first_param&.type
1737
+ end
1738
+ end
1739
+
1740
+ if var_type
1741
+ if body
1742
+ body_constr = constr.with_updated_context(
1743
+ lvar_env: constr.context.lvar_env.assign(asgn.children[0].name, node: asgn, type: var_type)
1744
+ )
1745
+
1746
+ typing.add_context_for_body(node, context: body_constr.context)
1747
+ _, _, body_context = body_constr.synthesize(body)
1748
+
1749
+ constr = constr.update_lvar_env {|env| env.join(constr.context.lvar_env, body_context.lvar_env) }
1750
+ else
1751
+ constr = self
1752
+ end
1753
+
1754
+ add_typing(node, type: collection_type, constr: constr)
1755
+ else
1756
+ fallback_to_any(node) do
1757
+ Errors::NoMethod.new(
1758
+ node: node,
1759
+ method: :each,
1760
+ type: collection_type
1761
+ )
1762
+ end
1763
+ end
1764
+ end
1675
1765
  when :while, :until
1676
1766
  yield_self do
1677
1767
  cond, body = node.children
1678
- _, constr = synthesize(cond)
1768
+ cond_type, constr = synthesize(cond)
1679
1769
 
1680
- logic = TypeInference::Logic.new(subtyping: checker)
1681
- truthy, falsey = logic.nodes(node: cond)
1770
+ interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
1771
+ truthy_env, falsy_env = interpreter.eval(env: constr.context.lvar_env, node: cond, type: cond_type)
1682
1772
 
1683
1773
  case node.type
1684
1774
  when :while
1685
- body_env, exit_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1775
+ body_env, exit_env = truthy_env, falsy_env
1686
1776
  when :until
1687
- exit_env, body_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
1777
+ exit_env, body_env = truthy_env, falsy_env
1688
1778
  end
1689
1779
 
1690
1780
  if body
@@ -1733,9 +1823,22 @@ module Steep
1733
1823
  end
1734
1824
 
1735
1825
  when :irange, :erange
1736
- types = node.children.map {|n| synthesize(n).type }
1737
- type = AST::Builtin::Range.instance_type(union_type(*types))
1738
- add_typing(node, type: type)
1826
+ begin_node, end_node = node.children
1827
+
1828
+ constr = self
1829
+ begin_type, constr = if begin_node
1830
+ constr.synthesize(begin_node)
1831
+ else
1832
+ [AST::Builtin.nil_type, constr]
1833
+ end
1834
+ end_type, constr = if end_node
1835
+ constr.synthesize(end_node)
1836
+ else
1837
+ [AST::Builtin.nil_type, constr]
1838
+ end
1839
+
1840
+ type = AST::Builtin::Range.instance_type(union_type(begin_type, end_type))
1841
+ add_typing(node, type: type, constr: constr)
1739
1842
 
1740
1843
  when :regexp
1741
1844
  each_child_node(node) do |child|
@@ -1753,9 +1856,36 @@ module Steep
1753
1856
 
1754
1857
  when :or_asgn, :and_asgn
1755
1858
  yield_self do
1756
- _, rhs = node.children
1757
- rhs_type = synthesize(rhs).type
1758
- add_typing(node, type: rhs_type)
1859
+ asgn, rhs = node.children
1860
+
1861
+ case asgn.type
1862
+ when :lvasgn
1863
+ type, constr = synthesize(rhs, hint: hint)
1864
+ constr.lvasgn(asgn, type)
1865
+ when :ivasgn
1866
+ type, constr = synthesize(rhs, hint: hint)
1867
+ constr.ivasgn(asgn, type)
1868
+ when :send
1869
+ rhs_ = node.updated(:send,
1870
+ [
1871
+ asgn.children[0],
1872
+ :"#{asgn.children[1]}=",
1873
+ asgn.children[2],
1874
+ rhs
1875
+ ])
1876
+ node_type = case node.type
1877
+ when :or_asgn
1878
+ :or
1879
+ when :and_asgn
1880
+ :and
1881
+ end
1882
+ node_ = node.updated(node_type, [asgn, rhs_])
1883
+
1884
+ synthesize(node_, hint: hint)
1885
+ else
1886
+ Steep.logger.error { "#{node.type} with #{asgn.type} lhs is not supported"}
1887
+ fallback_to_any(node)
1888
+ end
1759
1889
  end
1760
1890
 
1761
1891
  when :defined?
@@ -1802,8 +1932,8 @@ module Steep
1802
1932
  param_type = hint.params.required[0]
1803
1933
  interface = checker.factory.interface(param_type, private: true)
1804
1934
  method = interface.methods[value.children[0]]
1805
- if method&.overload?
1806
- return_types = method.types.select {|method_type|
1935
+ if method
1936
+ return_types = method.method_types.select {|method_type|
1807
1937
  method_type.params.each_type.count == 0
1808
1938
  }.map(&:return_type)
1809
1939
 
@@ -1831,9 +1961,50 @@ module Steep
1831
1961
  add_typing node, type: AST::Builtin.any_type
1832
1962
  end
1833
1963
 
1834
- when :splat, :sclass, :alias
1964
+ when :cvasgn
1965
+ name, rhs = node.children
1966
+
1967
+ type, constr = synthesize(rhs, hint: hint)
1968
+
1969
+ var_type = if module_context&.class_variables
1970
+ module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
1971
+ end
1972
+
1973
+ if var_type
1974
+ result = constr.check_relation(sub_type: type, super_type: var_type)
1975
+
1976
+ if result.success?
1977
+ add_typing node, type: type, constr: constr
1978
+ else
1979
+ fallback_to_any node do
1980
+ Errors::IncompatibleAssignment.new(node: node,
1981
+ lhs_type: var_type,
1982
+ rhs_type: type,
1983
+ result: result)
1984
+ end
1985
+ end
1986
+ else
1987
+ fallback_to_any(node)
1988
+ end
1989
+
1990
+ when :cvar
1991
+ name = node.children[0]
1992
+ var_type = if module_context&.class_variables
1993
+ module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
1994
+ end
1995
+
1996
+ if var_type
1997
+ add_typing node, type: var_type
1998
+ else
1999
+ fallback_to_any node
2000
+ end
2001
+
2002
+ when :alias
2003
+ add_typing node, type: AST::Builtin.nil_type
2004
+
2005
+ when :splat
1835
2006
  yield_self do
1836
- Steep.logger.error "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})"
2007
+ Steep.logger.warn { "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})" }
1837
2008
 
1838
2009
  each_child_node node do |child|
1839
2010
  synthesize(child)
@@ -1842,8 +2013,18 @@ module Steep
1842
2013
  add_typing node, type: AST::Builtin.any_type
1843
2014
  end
1844
2015
 
2016
+ when :args
2017
+ constr = self
2018
+
2019
+ each_child_node(node) do |child|
2020
+ _, constr = constr.synthesize(child)
2021
+ end
2022
+
2023
+ add_typing node, type: AST::Builtin.any_type, constr: constr
2024
+
1845
2025
  else
1846
2026
  raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
2027
+
1847
2028
  end.tap do |pair|
1848
2029
  unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
1849
2030
  # Steep.logger.error { "result = #{pair.inspect}" }
@@ -1883,136 +2064,202 @@ module Steep
1883
2064
  add_typing(node, type: ivar_type)
1884
2065
  end
1885
2066
 
2067
+ def masgn_lhs?(lhs)
2068
+ lhs.children.all? do |a|
2069
+ asgn_type = if a.type == :splat
2070
+ a.children[0].type
2071
+ else
2072
+ a.type
2073
+ end
2074
+ asgn_type == :lvasgn || asgn_type == :ivasgn
2075
+ end
2076
+ end
2077
+
2078
+ def lvasgn(node, type)
2079
+ name = node.children[0].name
2080
+ env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
2081
+ typing.add_error(
2082
+ Errors::IncompatibleAssignment.new(node: node,
2083
+ lhs_type: declared_type,
2084
+ rhs_type: type,
2085
+ result: result)
2086
+ )
2087
+ end
2088
+
2089
+ add_typing(node, type: type, constr: with_updated_context(lvar_env: env))
2090
+ end
2091
+
2092
+ def ivasgn(node, type)
2093
+ ivar = node.children[0]
2094
+
2095
+ type_env.assign(ivar: ivar, type: type, self_type: self_type) do |error|
2096
+ case error
2097
+ when Subtyping::Result::Failure
2098
+ var_type = type_env.get(ivar: ivar)
2099
+ typing.add_error(Errors::IncompatibleAssignment.new(node: node,
2100
+ lhs_type: var_type,
2101
+ rhs_type: type,
2102
+ result: error))
2103
+ when nil
2104
+ fallback_to_any node
2105
+ end
2106
+ end
2107
+
2108
+ add_typing(node, type: type)
2109
+ end
2110
+
1886
2111
  def type_masgn(node)
1887
2112
  lhs, rhs = node.children
1888
2113
  rhs_pair = synthesize(rhs)
1889
- rhs_type = expand_alias(rhs_pair.type)
2114
+ rhs_type = deep_expand_alias(rhs_pair.type)
1890
2115
 
1891
2116
  constr = rhs_pair.constr
1892
2117
 
1893
- if lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
1894
- case
1895
- when rhs.type == :array && lhs.children.size == rhs.children.size
1896
- # a, @b = x, y
2118
+ unless masgn_lhs?(lhs)
2119
+ Steep.logger.error("Unsupported masgn lhs node: only lvasgn, ivasgn, and splat are supported")
2120
+ _, constr = constr.fallback_to_any(lhs)
2121
+ return add_typing(node, type: rhs_type, constr: constr)
2122
+ end
1897
2123
 
1898
- constr = lhs.children.zip(rhs.children).inject(constr) do |ctr, (lhs, rhs)|
1899
- case lhs.type
1900
- when :lvasgn
1901
- name = lhs.children[0].name
1902
- type = typing.type_of(node: rhs)
1903
- env = ctr.context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
1904
- typing.add_error(
1905
- Errors::IncompatibleAssignment.new(node: lhs,
1906
- lhs_type: declared_type,
1907
- rhs_type: type,
1908
- result: result)
1909
- )
1910
- end
1911
- add_typing(lhs,
1912
- type: type,
1913
- constr: ctr.with_updated_context(lvar_env: env))
1914
- when :ivasgn
1915
- type_ivasgn(lhs.children.first, rhs, lhs)
1916
- constr
1917
- end
2124
+ falseys, truthys = partition_flatten_types(rhs_type) do |type|
2125
+ type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
2126
+ end
2127
+
2128
+ unwrap_rhs_type = AST::Types::Union.build(types: truthys)
2129
+
2130
+ case
2131
+ when unwrap_rhs_type.is_a?(AST::Types::Tuple) || (rhs.type == :array && rhs.children.none? {|n| n.type == :splat })
2132
+ tuple_types = if unwrap_rhs_type.is_a?(AST::Types::Tuple)
2133
+ unwrap_rhs_type.types.dup
2134
+ else
2135
+ rhs.children.map do |node|
2136
+ typing.type_of(node: node)
2137
+ end
2138
+ end
2139
+
2140
+ assignment_nodes = lhs.children.dup
2141
+ leading_assignments = []
2142
+ trailing_assignments = []
2143
+
2144
+ until assignment_nodes.empty?
2145
+ cursor = assignment_nodes.first
2146
+
2147
+ if cursor.type == :splat
2148
+ break
2149
+ else
2150
+ leading_assignments << assignment_nodes.shift
1918
2151
  end
2152
+ end
1919
2153
 
1920
- add_typing(node, type: rhs_type, constr: constr)
2154
+ until assignment_nodes.empty?
2155
+ cursor = assignment_nodes.last
1921
2156
 
1922
- when rhs_type.is_a?(AST::Types::Tuple)
1923
- # a, @b = tuple
2157
+ if cursor.type == :splat
2158
+ break
2159
+ else
2160
+ trailing_assignments.unshift assignment_nodes.pop
2161
+ end
2162
+ end
1924
2163
 
1925
- constr = lhs.children.zip(rhs_type.types).inject(constr) do |ctr, (lhs, type)|
1926
- ty = type || AST::Builtin.nil_type
2164
+ leading_assignments.each do |asgn|
2165
+ type = tuple_types.first
1927
2166
 
1928
- case lhs.type
1929
- when :lvasgn
1930
- name = lhs.children[0].name
1931
- env = ctr.context.lvar_env.assign(name, node: node, type: ty) do |declared_type, type, result|
1932
- typing.add_error(
1933
- Errors::IncompatibleAssignment.new(node: lhs,
1934
- lhs_type: declared_type,
1935
- rhs_type: type,
1936
- result: result)
1937
- )
1938
- end
1939
- add_typing(lhs,
1940
- type: ty,
1941
- constr: ctr.with_updated_context(lvar_env: env)).constr
1942
- when :ivasgn
1943
- ivar = lhs.children[0]
2167
+ if type
2168
+ tuple_types.shift
2169
+ else
2170
+ type = AST::Builtin.nil_type
2171
+ end
1944
2172
 
1945
- type_env.assign(ivar: ivar, type: ty, self_type: self_type) do |error|
1946
- case error
1947
- when Subtyping::Result::Failure
1948
- ivar_type = type_env.get(ivar: ivar)
1949
- typing.add_error(Errors::IncompatibleAssignment.new(node: lhs,
1950
- lhs_type: ivar_type,
1951
- rhs_type: ty,
1952
- result: error))
1953
- when nil
1954
- fallback_to_any node
1955
- end
1956
- end
2173
+ case asgn.type
2174
+ when :lvasgn
2175
+ _, constr = constr.lvasgn(asgn, type)
2176
+ when :ivasgn
2177
+ _, constr = constr.ivasgn(asgn, type)
2178
+ end
2179
+ end
1957
2180
 
1958
- ctr
1959
- end
2181
+ trailing_assignments.reverse_each do |asgn|
2182
+ type = tuple_types.last
2183
+
2184
+ if type
2185
+ tuple_types.pop
2186
+ else
2187
+ type = AST::Builtin.nil_type
1960
2188
  end
1961
2189
 
1962
- add_typing(node, type: rhs_type, constr: constr)
2190
+ case asgn.type
2191
+ when :lvasgn
2192
+ _, constr = constr.lvasgn(asgn, type)
2193
+ when :ivasgn
2194
+ _, constr = constr.ivasgn(asgn, type)
2195
+ end
2196
+ end
1963
2197
 
1964
- when AST::Builtin::Array.instance_type?(rhs_type)
1965
- element_type = AST::Types::Union.build(types: [rhs_type.args.first, AST::Builtin.nil_type])
2198
+ element_type = if tuple_types.empty?
2199
+ AST::Builtin.nil_type
2200
+ else
2201
+ AST::Types::Union.build(types: tuple_types)
2202
+ end
2203
+ array_type = AST::Builtin::Array.instance_type(element_type)
1966
2204
 
1967
- constr = lhs.children.inject(constr) do |ctr, assignment|
1968
- case assignment.type
2205
+ assignment_nodes.each do |asgn|
2206
+ case asgn.type
2207
+ when :splat
2208
+ case asgn.children[0].type
1969
2209
  when :lvasgn
1970
- name = assignment.children[0].name
1971
- env = ctr.context.lvar_env.assign(name, node: node, type: element_type) do |declared_type, type, result|
1972
- typing.add_error(
1973
- Errors::IncompatibleAssignment.new(node: assignment,
1974
- lhs_type: declared_type,
1975
- rhs_type: type,
1976
- result: result)
1977
- )
1978
- end
2210
+ _, constr = constr.lvasgn(asgn.children[0], array_type)
2211
+ when :ivasgn
2212
+ _, constr = constr.ivasgn(asgn.children[0], array_type)
2213
+ end
2214
+ when :lvasgn
2215
+ _, constr = constr.lvasgn(asgn, element_type)
2216
+ when :ivasgn
2217
+ _,constr = constr.ivasgn(asgn, element_type)
2218
+ end
2219
+ end
1979
2220
 
1980
- add_typing(assignment,
1981
- type: element_type,
1982
- constr: ctr.with_updated_context(lvar_env: env)).constr
2221
+ unless falseys.empty?
2222
+ constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
2223
+ end
1983
2224
 
1984
- when :ivasgn
1985
- ivar = assignment.children[0]
2225
+ add_typing(node, type: rhs_type, constr: constr)
1986
2226
 
1987
- type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
1988
- case error
1989
- when Subtyping::Result::Failure
1990
- type = type_env.get(ivar: ivar)
1991
- typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
1992
- lhs_type: type,
1993
- rhs_type: element_type,
1994
- result: error))
1995
- when nil
1996
- fallback_to_any node
1997
- end
1998
- end
2227
+ when flatten_union(unwrap_rhs_type).all? {|type| AST::Builtin::Array.instance_type?(type) }
2228
+ array_elements = flatten_union(unwrap_rhs_type).map {|type| type.args[0] }
2229
+ element_type = AST::Types::Union.build(types: array_elements + [AST::Builtin.nil_type])
2230
+
2231
+ constr = lhs.children.inject(constr) do |constr, assignment|
2232
+ case assignment.type
2233
+ when :lvasgn
2234
+ _, constr = constr.lvasgn(assignment, element_type)
1999
2235
 
2000
- ctr
2236
+ when :ivasgn
2237
+ _, constr = constr.ivasgn(assignment, element_type)
2238
+ when :splat
2239
+ case assignment.children[0].type
2240
+ when :lvasgn
2241
+ _, constr = constr.lvasgn(assignment.children[0], unwrap_rhs_type)
2242
+ when :ivasgn
2243
+ _, constr = constr.ivasgn(assignment.children[0], unwrap_rhs_type)
2244
+ else
2245
+ raise
2001
2246
  end
2002
2247
  end
2003
2248
 
2004
- add_typing node, type: rhs_type, constr: constr
2005
-
2006
- when rhs_type.is_a?(AST::Types::Any)
2007
- fallback_to_any(node)
2249
+ constr
2250
+ end
2008
2251
 
2009
- else
2010
- Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
2011
- fallback_to_any(node)
2252
+ unless falseys.empty?
2253
+ constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
2012
2254
  end
2255
+
2256
+ add_typing(node, type: rhs_type, constr: constr)
2013
2257
  else
2014
- Steep.logger.error("Unsupported masgn left hand side")
2015
- fallback_to_any(node)
2258
+ unless rhs_type.is_a?(AST::Types::Any)
2259
+ Steep.logger.error("Unsupported masgn rhs type: array or tuple is supported (#{rhs_type})")
2260
+ end
2261
+ _, constr = constr.fallback_to_any(lhs)
2262
+ add_typing(node, type: rhs_type, constr: constr)
2016
2263
  end
2017
2264
  end
2018
2265
 
@@ -2040,7 +2287,7 @@ module Steep
2040
2287
 
2041
2288
  def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
2042
2289
  receiver, method_name, *arguments = send_node.children
2043
- receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
2290
+ receiver_type, constr = receiver ? synthesize(receiver) : [AST::Types::Self.new, self]
2044
2291
 
2045
2292
  if unwrap
2046
2293
  receiver_type = unwrap(receiver_type)
@@ -2048,74 +2295,80 @@ module Steep
2048
2295
 
2049
2296
  receiver_type = expand_alias(receiver_type)
2050
2297
 
2051
- pair = case receiver_type
2052
- when AST::Types::Any
2053
- add_typing node, type: AST::Builtin.any_type
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
2054
2305
 
2055
- when nil
2056
- fallback_to_any node
2306
+ add_typing node, type: AST::Builtin.any_type
2057
2307
 
2058
- when AST::Types::Void, AST::Types::Bot, AST::Types::Top
2059
- fallback_to_any node do
2060
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2061
- end
2308
+ when nil
2309
+ fallback_to_any node
2062
2310
 
2063
- else
2064
- case expanded_receiver_type = expand_self(receiver_type)
2065
- when AST::Types::Self
2066
- Steep.logger.error "`self` type cannot be resolved to concrete type"
2067
- fallback_to_any node do
2068
- Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
2069
- end
2070
- else
2071
- begin
2072
- interface = checker.factory.interface(receiver_type,
2073
- private: !receiver,
2074
- self_type: expanded_receiver_type)
2075
-
2076
- method = interface.methods[method_name]
2077
-
2078
- if method
2079
- args = TypeInference::SendArgs.from_nodes(arguments)
2080
- return_type, constr, _ = type_method_call(node,
2081
- method: method,
2082
- method_name: method_name,
2083
- args: args,
2084
- block_params: block_params,
2085
- block_body: block_body,
2086
- receiver_type: receiver_type,
2087
- topdown_hint: true)
2088
-
2089
- add_typing node, type: return_type, constr: constr
2090
- else
2091
- fallback_to_any node do
2092
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2093
- end
2094
- end
2095
- rescue => exn
2096
- case exn
2097
- when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2098
- # ignore known RBS errors.
2099
- else
2100
- Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
2101
- end
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
2102
2315
 
2103
- fallback_to_any node do
2104
- Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
2105
- end
2106
- end
2107
- end
2108
- end
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
2355
+
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
2109
2362
 
2110
- case pair.type
2363
+ case type
2111
2364
  when nil, Errors::Base
2112
2365
  arguments.each do |arg|
2113
2366
  unless typing.has_type?(arg)
2114
2367
  if arg.type == :splat
2115
- type = synthesize(arg.children[0]).type
2368
+ type, constr = constr.synthesize(arg.children[0])
2116
2369
  add_typing(arg, type: AST::Builtin::Array.instance_type(type))
2117
2370
  else
2118
- synthesize(arg)
2371
+ _, constr = constr.synthesize(arg)
2119
2372
  end
2120
2373
  end
2121
2374
  end
@@ -2137,7 +2390,7 @@ module Steep
2137
2390
  end
2138
2391
  end
2139
2392
  else
2140
- pair
2393
+ Pair.new(type: type, constr: constr)
2141
2394
  end
2142
2395
  end
2143
2396
 
@@ -2204,139 +2457,68 @@ module Steep
2204
2457
  def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
2205
2458
  node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
2206
2459
 
2207
- case
2208
- when method.union?
2209
- yield_self do
2210
- results = method.types.map do |method|
2460
+ results = method.method_types.flat_map do |method_type|
2461
+ Steep.logger.tagged method_type.to_s do
2462
+ zips = args.zips(method_type.params, method_type.block&.type)
2463
+
2464
+ zips.map do |arg_pairs|
2211
2465
  typing.new_child(node_range) do |child_typing|
2212
- with_new_typing(child_typing).type_method_call(node,
2213
- method_name: method_name,
2214
- receiver_type: receiver_type,
2215
- method: method,
2216
- args: args,
2217
- block_params: block_params,
2218
- block_body: block_body,
2219
- topdown_hint: false)
2220
- end
2221
- end
2466
+ ret = self.with_new_typing(child_typing).try_method_type(
2467
+ node,
2468
+ receiver_type: receiver_type,
2469
+ method_type: method_type,
2470
+ args: args,
2471
+ arg_pairs: arg_pairs,
2472
+ block_params: block_params,
2473
+ block_body: block_body,
2474
+ child_typing: child_typing,
2475
+ topdown_hint: topdown_hint
2476
+ )
2222
2477
 
2223
- if (type, constr, error = results.find {|_, _, error| error })
2224
- constr.typing.save!
2225
- [type,
2226
- update_lvar_env { constr.context.lvar_env },
2227
- error]
2228
- else
2229
- types = results.map(&:first)
2478
+ raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2230
2479
 
2231
- _, constr, _ = results.first
2232
- constr.typing.save!
2480
+ result, constr = ret
2233
2481
 
2234
- [union_type(*types),
2235
- update_lvar_env { constr.context.lvar_env },
2236
- nil]
2482
+ [result, constr, method_type]
2483
+ end
2237
2484
  end
2238
2485
  end
2486
+ end
2239
2487
 
2240
- when method.intersection?
2241
- yield_self do
2242
- results = method.types.map do |method|
2243
- typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
2244
- with_new_typing(child_typing).type_method_call(node,
2488
+ unless results.empty?
2489
+ result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2490
+ else
2491
+ method_type = method.method_types.last
2492
+ 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
2507
+ else
2508
+ typing.add_error Errors::UnresolvedOverloading.new(node: node,
2509
+ receiver_type: expand_self(receiver_type),
2245
2510
  method_name: method_name,
2246
- receiver_type: receiver_type,
2247
- method: method,
2248
- args: args,
2249
- block_params: block_params,
2250
- block_body: block_body,
2251
- topdown_hint: false)
2252
- end
2253
- end
2254
-
2255
- successes = results.reject {|_, _, error| error }
2256
- unless successes.empty?
2257
- types = successes.map(&:first)
2258
- constr = successes[0][1]
2259
- constr.typing.save!
2260
-
2261
- [AST::Types::Intersection.build(types: types),
2262
- update_lvar_env { constr.context.lvar_env },
2263
- nil]
2264
- else
2265
- type, constr, error = results.first
2266
- constr.typing.save!
2267
-
2268
- [type,
2269
- update_lvar_env { constr.context.lvar_env },
2270
- error]
2271
- end
2511
+ method_types: method.method_types)
2512
+ type = AST::Builtin.any_type
2272
2513
  end
2273
2514
 
2274
- when method.overload?
2275
- yield_self do
2276
- results = method.types.flat_map do |method_type|
2277
- Steep.logger.tagged method_type.to_s do
2278
- zips = args.zips(method_type.params, method_type.block&.type)
2279
-
2280
- zips.map do |arg_pairs|
2281
- typing.new_child(node_range) do |child_typing|
2282
- ret = self.with_new_typing(child_typing).try_method_type(
2283
- node,
2284
- receiver_type: receiver_type,
2285
- method_type: method_type,
2286
- args: args,
2287
- arg_pairs: arg_pairs,
2288
- block_params: block_params,
2289
- block_body: block_body,
2290
- child_typing: child_typing,
2291
- topdown_hint: topdown_hint
2292
- )
2293
-
2294
- raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
2295
-
2296
- result, constr = ret
2297
-
2298
- [result, constr, method_type]
2299
- end
2300
- end
2301
- end
2302
- end
2303
-
2304
- unless results.empty?
2305
- result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
2306
- else
2307
- method_type = method.types.last
2308
- constr = self.with_new_typing(typing.new_child(node_range))
2309
- result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
2310
- end
2311
- constr.typing.save!
2312
-
2313
- case result
2314
- when Errors::Base
2315
- if method.types.size == 1
2316
- typing.add_error result
2317
- type = case method_type.return_type
2318
- when AST::Types::Var
2319
- AST::Builtin.any_type
2320
- else
2321
- method_type.return_type
2322
- end
2323
- else
2324
- typing.add_error Errors::UnresolvedOverloading.new(node: node,
2325
- receiver_type: expand_self(receiver_type),
2326
- method_name: method_name,
2327
- method_types: method.types)
2328
- type = AST::Builtin.any_type
2329
- end
2330
-
2331
- [type,
2332
- update_lvar_env { constr.context.lvar_env },
2333
- result]
2334
- else # Type
2335
- [result,
2336
- update_lvar_env { constr.context.lvar_env },
2337
- nil]
2338
- end
2339
- end
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]
2340
2522
  end
2341
2523
  end
2342
2524
 
@@ -2523,16 +2705,40 @@ module Steep
2523
2705
  if block_params && method_type.block
2524
2706
  block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2525
2707
  block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
2526
- block_param_hint = block_params_.params_type(
2527
- hint: topdown_hint ? method_type.block.type.params : nil
2528
- )
2529
2708
 
2530
- check_relation(sub_type: AST::Types::Proc.new(params: block_param_hint, return_type: AST::Types::Any.new),
2531
- super_type: method_type.block.type,
2532
- constraints: constraints).else do |result|
2533
- return [Errors::IncompatibleBlockParameters.new(node: node,
2534
- method_type: method_type),
2535
- constr]
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
+ ]
2740
+ end
2741
+ end
2536
2742
  end
2537
2743
  end
2538
2744
 
@@ -2683,7 +2889,7 @@ module Steep
2683
2889
  decls = param_types_hash.each.with_object({}) do |(name, type), hash|
2684
2890
  hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
2685
2891
  end
2686
- env.update(declared_types: env.declared_types.merge(decls))
2892
+ env.except(decls.keys).update(assigned_types: decls)
2687
2893
  end.annotate(block_annotations)
2688
2894
 
2689
2895
  break_type = if block_annotations.break_type
@@ -2826,7 +3032,7 @@ module Steep
2826
3032
  end
2827
3033
 
2828
3034
  def nested_namespace_for_module(module_name)
2829
- if module_name.relative?
3035
+ if module_name.namespace.relative?
2830
3036
  (current_namespace + module_name.namespace).append(module_name.name)
2831
3037
  else
2832
3038
  module_name
@@ -2835,7 +3041,7 @@ module Steep
2835
3041
 
2836
3042
  def absolute_name(module_name)
2837
3043
  if current_namespace
2838
- module_name.in_namespace(current_namespace)
3044
+ module_name.with_prefix(current_namespace)
2839
3045
  else
2840
3046
  module_name.absolute!
2841
3047
  end
@@ -2853,7 +3059,7 @@ module Steep
2853
3059
  end
2854
3060
 
2855
3061
  def validate_method_definitions(node, module_name)
2856
- module_name_1 = checker.factory.type_name_1(module_name.name)
3062
+ module_name_1 = module_name.name
2857
3063
  member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
2858
3064
 
2859
3065
  return unless member_decl_count == 1
@@ -3001,20 +3207,31 @@ module Steep
3001
3207
  end
3002
3208
  end
3003
3209
 
3004
- def deep_expand_alias(type, recursive: Set.new, &block)
3005
- raise "Recursive type definition: #{type}" if recursive.member?(type)
3210
+ def deep_expand_alias(type, &block)
3211
+ checker.factory.deep_expand_alias(type, &block)
3212
+ end
3006
3213
 
3007
- ty = case type
3008
- when AST::Types::Name::Alias
3009
- deep_expand_alias(expand_alias(type), recursive: recursive << type)
3010
- else
3011
- type
3012
- end
3214
+ def flatten_union(type)
3215
+ checker.factory.flatten_union(type)
3216
+ end
3013
3217
 
3014
- if block_given?
3015
- yield ty
3016
- else
3017
- ty
3218
+ def select_flatten_types(type, &block)
3219
+ types = flatten_union(deep_expand_alias(type))
3220
+ types.select(&block)
3221
+ end
3222
+
3223
+ def partition_flatten_types(type, &block)
3224
+ types = flatten_union(deep_expand_alias(type))
3225
+ types.partition(&block)
3226
+ end
3227
+
3228
+ def flatten_array_elements(type)
3229
+ flatten_union(deep_expand_alias(type)).flat_map do |type|
3230
+ if AST::Builtin::Array.instance_type?(type)
3231
+ type.args
3232
+ else
3233
+ [type]
3234
+ end
3018
3235
  end
3019
3236
  end
3020
3237
 
@@ -3056,8 +3273,8 @@ module Steep
3056
3273
 
3057
3274
  def to_instance_type(type, args: nil)
3058
3275
  args = args || case type
3059
- when AST::Types::Name::Class, AST::Types::Name::Module
3060
- checker.factory.env.class_decls[checker.factory.type_name_1(type.name)].type_params.each.map { AST::Builtin.any_type }
3276
+ when AST::Types::Name::Singleton
3277
+ checker.factory.env.class_decls[type.name].type_params.each.map { AST::Builtin.any_type }
3061
3278
  else
3062
3279
  raise "unexpected type to to_instance_type: #{type}"
3063
3280
  end
@@ -3065,6 +3282,47 @@ module Steep
3065
3282
  AST::Types::Name::Instance.new(name: type.name, args: args)
3066
3283
  end
3067
3284
 
3285
+ def try_tuple_type(node, hint)
3286
+ if node.children.size != hint.types.size
3287
+ return
3288
+ end
3289
+
3290
+ constr = self
3291
+ element_types = []
3292
+
3293
+ each_child_node(node).with_index do |child, index|
3294
+ type, constr = constr.synthesize(child, hint: hint.types[index])
3295
+ element_types << type
3296
+ end
3297
+
3298
+ constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
3299
+ end
3300
+
3301
+ def try_array_type(node, hint)
3302
+ element_hint = hint ? hint.args[0] : nil
3303
+
3304
+ constr = self
3305
+ element_types = []
3306
+
3307
+ each_child_node(node) do |child|
3308
+ case child.type
3309
+ when :splat
3310
+ type, constr = constr.synthesize(child.children[0], hint: hint)
3311
+ if AST::Builtin::Array.instance_type?(type)
3312
+ element_types << type.args[0]
3313
+ else
3314
+ element_types.push(*flatten_array_elements(type))
3315
+ end
3316
+ else
3317
+ type, constr = constr.synthesize(child, hint: element_hint)
3318
+ element_types << type
3319
+ end
3320
+ end
3321
+
3322
+ element_type = AST::Types::Union.build(types: element_types)
3323
+ constr.add_typing(node, type: AST::Builtin::Array.instance_type(element_type))
3324
+ end
3325
+
3068
3326
  def try_hash_type(node, hint)
3069
3327
  case hint
3070
3328
  when AST::Types::Record