steep 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/LICENSE +21 -0
  4. data/bin/smoke_runner.rb +3 -0
  5. data/lib/steep/ast/annotation/collection.rb +120 -43
  6. data/lib/steep/ast/annotation.rb +5 -10
  7. data/lib/steep/ast/location.rb +1 -1
  8. data/lib/steep/ast/method_type.rb +3 -1
  9. data/lib/steep/ast/signature/alias.rb +19 -0
  10. data/lib/steep/ast/signature/env.rb +9 -0
  11. data/lib/steep/ast/signature/members.rb +4 -0
  12. data/lib/steep/ast/types/proc.rb +79 -0
  13. data/lib/steep/ast/types/void.rb +4 -0
  14. data/lib/steep/cli.rb +2 -1
  15. data/lib/steep/drivers/check.rb +4 -1
  16. data/lib/steep/errors.rb +13 -0
  17. data/lib/steep/interface/builder.rb +90 -47
  18. data/lib/steep/interface/instantiated.rb +1 -1
  19. data/lib/steep/interface/method.rb +8 -0
  20. data/lib/steep/interface/method_type.rb +40 -13
  21. data/lib/steep/parser.rb +1098 -1043
  22. data/lib/steep/parser.y +94 -36
  23. data/lib/steep/source.rb +5 -6
  24. data/lib/steep/subtyping/check.rb +162 -47
  25. data/lib/steep/subtyping/variable_occurrence.rb +2 -2
  26. data/lib/steep/subtyping/variable_variance.rb +3 -3
  27. data/lib/steep/type_construction.rb +630 -300
  28. data/lib/steep/type_inference/block_params.rb +186 -35
  29. data/lib/steep/type_inference/send_args.rb +12 -3
  30. data/lib/steep/type_inference/type_env.rb +10 -4
  31. data/lib/steep/type_name.rb +6 -0
  32. data/lib/steep/typing.rb +21 -2
  33. data/lib/steep/version.rb +1 -1
  34. data/lib/steep.rb +2 -0
  35. data/smoke/alias/a.rb +19 -0
  36. data/smoke/alias/a.rbi +10 -0
  37. data/smoke/alias/b.rb +7 -0
  38. data/smoke/alias/c.rb +10 -0
  39. data/smoke/array/c.rb +7 -0
  40. data/smoke/block/c.rb +10 -0
  41. data/smoke/block/c.rbi +3 -0
  42. data/smoke/block/d.rb +15 -0
  43. data/smoke/class/c.rb +1 -1
  44. data/smoke/class/e.rb +1 -1
  45. data/smoke/class/h.rb +15 -0
  46. data/smoke/class/h.rbi +7 -0
  47. data/smoke/class/i.rb +17 -0
  48. data/smoke/class/i.rbi +9 -0
  49. data/smoke/extension/a.rbi +4 -0
  50. data/smoke/extension/d.rb +2 -0
  51. data/smoke/hash/a.rb +17 -0
  52. data/smoke/hash/b.rb +7 -0
  53. data/smoke/implements/a.rb +2 -2
  54. data/smoke/initialize/a.rb +1 -1
  55. data/smoke/lambda/a.rb +11 -0
  56. data/smoke/literal/b.rb +9 -0
  57. data/smoke/literal/literal_methods.rbi +4 -0
  58. data/smoke/method/c.rb +5 -0
  59. data/smoke/regression/array.rb +7 -0
  60. data/smoke/regression/hash.rb +7 -0
  61. data/smoke/regression/set_divide.rb +16 -0
  62. data/smoke/self/a.rb +2 -2
  63. data/stdlib/builtin.rbi +151 -1
  64. data/steep.gemspec +1 -0
  65. metadata +30 -4
data/lib/steep/parser.y CHANGED
@@ -92,17 +92,22 @@ optional_keyword: QUESTION keyword COLON type { result = [val[0].location + val[
92
92
  val[3]] }
93
93
 
94
94
  block_opt: { result = nil }
95
- | LBRACE RBRACE {
95
+ | block_optional LBRACE RBRACE {
96
96
  result = AST::MethodType::Block.new(params: nil,
97
97
  return_type: nil,
98
- location: val[0].location + val[1].location)
98
+ location: (val[0] || val[1]).location + val[2].location,
99
+ optional: val[0]&.value || false)
99
100
  }
100
- | LBRACE block_params ARROW type RBRACE {
101
- result = AST::MethodType::Block.new(params: val[1],
102
- return_type: val[3],
103
- location: val[0].location + val[4].location)
101
+ | block_optional LBRACE block_params ARROW type RBRACE {
102
+ result = AST::MethodType::Block.new(params: val[2],
103
+ return_type: val[4],
104
+ location: (val[0] || val[1]).location + val[5].location,
105
+ optional: val[0]&.value || false)
104
106
  }
105
107
 
108
+ block_optional: { result = nil }
109
+ | QUESTION { result = LocatedValue.new(location: val[0].location, value: true) }
110
+
106
111
  block_params: { result = nil }
107
112
  | LPAREN block_params0 RPAREN {
108
113
  result = val[1]
@@ -139,7 +144,7 @@ block_params2: { result = nil }
139
144
  simple_type: type_name {
140
145
  result = AST::Types::Name.new(name: val[0].value, location: val[0].location, args: [])
141
146
  }
142
- | instance_type_name LT type_seq GT {
147
+ | application_type_name LT type_seq GT {
143
148
  loc = val[0].location + val[3].location
144
149
  name = val[0].value
145
150
  args = val[2]
@@ -175,16 +180,20 @@ simple_type: type_name {
175
180
  paren_type: LPAREN type RPAREN { result = val[1].with_location(val[0].location + val[2].location) }
176
181
  | simple_type
177
182
 
178
- instance_type_name: module_name {
179
- result = LocatedValue.new(value: TypeName::Instance.new(name: val[0].value),
180
- location: val[0].location)
181
- }
182
- | INTERFACE_NAME {
183
- result = LocatedValue.new(value: TypeName::Interface.new(name: val[0].value),
184
- location: val[0].location)
185
- }
186
-
187
- type_name: instance_type_name
183
+ application_type_name: module_name {
184
+ result = LocatedValue.new(value: TypeName::Instance.new(name: val[0].value),
185
+ location: val[0].location)
186
+ }
187
+ | INTERFACE_NAME {
188
+ result = LocatedValue.new(value: TypeName::Interface.new(name: val[0].value),
189
+ location: val[0].location)
190
+ }
191
+ | LIDENT {
192
+ result = LocatedValue.new(value: TypeName::Alias.new(name: val[0].value),
193
+ location: val[0].location)
194
+ }
195
+
196
+ type_name: application_type_name
188
197
  | module_name DOT CLASS constructor {
189
198
  loc = val[0].location + (val[3] || val[2]).location
190
199
  result = LocatedValue.new(value: TypeName::Class.new(name: val[0].value, constructor: val[3]&.value),
@@ -197,14 +206,30 @@ type_name: instance_type_name
197
206
  }
198
207
 
199
208
  constructor: { result = nil }
200
- | CONSTRUCTOR
201
- | NOCONSTRUCTOR
209
+ | CONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: true) }
210
+ | NOCONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: false) }
202
211
 
203
212
  type: paren_type
204
213
  | union_seq {
205
214
  loc = val[0].first.location + val[0].last.location
206
215
  result = AST::Types::Union.build(types: val[0], location: loc)
207
216
  }
217
+ | HAT LPAREN lambda_params RPAREN ARROW paren_type {
218
+ loc = val[0].location + val[5].location
219
+ result = AST::Types::Proc.new(params: val[2], return_type: val[5], location: loc)
220
+ }
221
+
222
+ lambda_params: lambda_params1
223
+ | paren_type { result = Interface::Params.empty.update(required: [val[0]]) }
224
+ | paren_type COMMA lambda_params {
225
+ result = val[2].update(required: [val[0]] + val[2].required)
226
+ }
227
+
228
+ lambda_params1: { result = Interface::Params.empty }
229
+ | STAR paren_type { result = Interface::Params.empty.update(rest: val[1]) }
230
+ | QUESTION paren_type { result = Interface::Params.empty.update(optional: [val[1]]) }
231
+ | QUESTION paren_type COMMA lambda_params1 { result = val[3].update(optional: [val[1]] + val[3].optional) }
232
+
208
233
 
209
234
  type_seq: type { result = [val[0]] }
210
235
  | type COMMA type_seq { result = [val[0]] + val[2] }
@@ -212,7 +237,7 @@ type_seq: type { result = [val[0]] }
212
237
  union_seq: simple_type BAR simple_type { result = [val[0], val[2]] }
213
238
  | simple_type BAR union_seq { result = [val[0]] + val[2] }
214
239
 
215
- keyword: IDENT
240
+ keyword: LIDENT
216
241
  | MODULE_NAME
217
242
  | INTERFACE_NAME
218
243
  | ANY
@@ -223,6 +248,7 @@ keyword: IDENT
223
248
  | INCLUDE
224
249
  | IVAR
225
250
  | SELF
251
+ | TYPE
226
252
 
227
253
  signatures: { result = [] }
228
254
  | interface signatures { result = [val[0]] + val[1] }
@@ -231,6 +257,7 @@ signatures: { result = [] }
231
257
  | extension_decl signatures { result = [val[0]] + val[1] }
232
258
  | const_decl signatures { result = [val[0]] + val[1] }
233
259
  | gvar_decl signatures { result = [val[0]] + val[1] }
260
+ | alias_decl signatures { result = [val[0]] + val[1] }
234
261
 
235
262
  gvar_decl: GVAR COLON type {
236
263
  loc = val.first.location + val.last.location
@@ -285,6 +312,14 @@ extension_decl: EXTENSION module_name type_params LPAREN UIDENT RPAREN class_mem
285
312
  members: val[6])
286
313
  }
287
314
 
315
+ alias_decl: TYPE LIDENT type_params EQ type {
316
+ loc = val[0].location + val[4].location
317
+ result = AST::Signature::Alias.new(location: loc,
318
+ name: val[1].value,
319
+ params: val[2],
320
+ type: val[4])
321
+ }
322
+
288
323
  self_type_opt: { result = nil }
289
324
  | COLON type { result = val[1] }
290
325
 
@@ -326,34 +361,34 @@ ivar_member: IVAR_NAME COLON type {
326
361
  )
327
362
  }
328
363
 
329
- instance_method_member: DEF constructor_method method_name COLON method_type_union {
364
+ instance_method_member: DEF method_annotations method_name COLON method_type_union {
330
365
  loc = val.first.location + val.last.last.location
331
366
  result = AST::Signature::Members::Method.new(
332
367
  name: val[2].value,
333
368
  types: val[4],
334
369
  kind: :instance,
335
370
  location: loc,
336
- attributes: [val[1] ? :constructor : nil].compact
371
+ attributes: val[1] || []
337
372
  )
338
373
  }
339
- module_method_member: DEF constructor_method SELF DOT method_name COLON method_type_union {
374
+ module_method_member: DEF method_annotations SELF DOT method_name COLON method_type_union {
340
375
  loc = val.first.location + val.last.last.location
341
376
  result = AST::Signature::Members::Method.new(
342
377
  name: val[4].value,
343
378
  types: val[6],
344
379
  kind: :module,
345
380
  location: loc,
346
- attributes: [val[1] ? :constructor : nil].compact
381
+ attributes: val[1] || []
347
382
  )
348
383
  }
349
- module_instance_method_member: DEF constructor_method SELFQ DOT method_name COLON method_type_union {
384
+ module_instance_method_member: DEF method_annotations SELFQ DOT method_name COLON method_type_union {
350
385
  loc = val.first.location + val.last.last.location
351
386
  result = AST::Signature::Members::Method.new(
352
387
  name: val[4].value,
353
388
  types: val[6],
354
389
  kind: :module_instance,
355
390
  location: loc,
356
- attributes: [val[1] ? :constructor : nil].compact
391
+ attributes: val[1] || []
357
392
  )
358
393
  }
359
394
  include_member: INCLUDE module_name {
@@ -389,8 +424,14 @@ attr_ivar_opt: { result = nil }
389
424
  | LPAREN RPAREN { result = false }
390
425
  | LPAREN IVAR_NAME RPAREN { result = val[1].value }
391
426
 
392
- constructor_method: { result = false }
393
- | LPAREN CONSTRUCTOR RPAREN { result = true }
427
+ method_annotations: { result = nil }
428
+ | LPAREN method_annotation_seq RPAREN { result = val[1] }
429
+
430
+ method_annotation_seq: method_annotation_keyword { result = [val[0]] }
431
+ | method_annotation_keyword COMMA method_annotation_seq { result = [val[0]] + val[2] }
432
+
433
+ method_annotation_keyword: CONSTRUCTOR { result = val[0].value }
434
+ | INCOMPATIBLE { result = val[0].value }
394
435
 
395
436
  super_opt: { result = nil }
396
437
  | LTCOLON super_class { result = val[1] }
@@ -428,6 +469,7 @@ method_name: method_name0
428
469
  | STAR | STAR2
429
470
  | PERCENT | MINUS
430
471
  | LT | GT
472
+ | UMINUS
431
473
  | BAR { result = LocatedValue.new(location: val[0].location, value: :|) }
432
474
  | method_name0 EQ {
433
475
  raise ParseError, "\nunexpected method name #{val[0].to_s} =" unless val[0].location.pred?(val[1].location)
@@ -448,8 +490,13 @@ method_name: method_name0
448
490
  raise ParseError, "\nunexpected method name > >" unless val[0].location.pred?(val[1].location)
449
491
  result = LocatedValue.new(location: val[0].location + val[1].location, value: :>>)
450
492
  }
493
+ | NIL QUESTION {
494
+ raise ParseError, "\nunexpected method name #{val[0].to_s} ?" unless val[0].location.pred?(val[1].location)
495
+ result = LocatedValue.new(location: val[0].location + val[1].location,
496
+ value: :"nil?")
497
+ }
451
498
 
452
- method_name0: IDENT
499
+ method_name0: LIDENT
453
500
  | UIDENT
454
501
  | MODULE_NAME
455
502
  | INTERFACE_NAME
@@ -463,15 +510,18 @@ method_name0: IDENT
463
510
  | EXTEND
464
511
  | INCLUDE
465
512
  | OPERATOR
513
+ | HAT
466
514
  | BANG
467
515
  | BLOCK
468
516
  | BREAK
469
517
  | METHOD
470
518
  | BOOL
519
+ | TYPE
471
520
  | CONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: :constructor) }
472
521
  | NOCONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: :noconstructor) }
473
522
  | ATTR_READER
474
523
  | ATTR_ACCESSOR
524
+ | INCOMPATIBLE
475
525
 
476
526
  annotation: AT_TYPE VAR subject COLON type {
477
527
  loc = val.first.location + val.last.location
@@ -545,7 +595,7 @@ dynamic_name: method_name {
545
595
  result = AST::Annotation::Dynamic::Name.new(name: val[2].value, location: loc, kind: :module_instance)
546
596
  }
547
597
 
548
- subject: IDENT { result = val[0] }
598
+ subject: LIDENT { result = val[0] }
549
599
 
550
600
  end
551
601
 
@@ -624,7 +674,7 @@ def next_token
624
674
  when input.scan(/\?/)
625
675
  new_token(:QUESTION)
626
676
  when input.scan(/!/)
627
- new_token(:BANG)
677
+ new_token(:BANG, :!)
628
678
  when input.scan(/\(/)
629
679
  new_token(:LPAREN, nil)
630
680
  when input.scan(/\)/)
@@ -651,7 +701,9 @@ def next_token
651
701
  new_token(:DOT)
652
702
  when input.scan(/<:/)
653
703
  new_token(:LTCOLON)
654
- when input.scan(/(\[\]=)|(\[\])|===|==|\^|!=|<</)
704
+ when input.scan(/\^/)
705
+ new_token(:HAT, :"^")
706
+ when input.scan(/(\[\]=)|(\[\])|===|==|!=|<<|=~/)
655
707
  new_token(:OPERATOR, input.matched.to_sym)
656
708
  when input.scan(/\[/)
657
709
  new_token(:LBRACKET, nil)
@@ -675,12 +727,18 @@ def next_token
675
727
  new_token(:ANY, :any)
676
728
  when input.scan(/void\b/)
677
729
  new_token(:VOID, :void)
730
+ when input.scan(/type\b/)
731
+ new_token(:TYPE, :type)
678
732
  when input.scan(/interface\b/)
679
733
  new_token(:INTERFACE, :interface)
734
+ when input.scan(/incompatible\b/)
735
+ new_token(:INCOMPATIBLE, :incompatible)
680
736
  when input.scan(/end\b/)
681
737
  new_token(:END, :end)
682
738
  when input.scan(/\|/)
683
739
  new_token(:BAR, :bar)
740
+ when input.scan(/-@/)
741
+ new_token(:UMINUS, :"-@")
684
742
  when input.scan(/def\b/)
685
743
  new_token(:DEF)
686
744
  when input.scan(/@type\b/)
@@ -738,9 +796,9 @@ def next_token
738
796
  when input.scan(/extension\b/)
739
797
  new_token(:EXTENSION, :extension)
740
798
  when input.scan(/constructor\b/)
741
- new_token(:CONSTRUCTOR, true)
799
+ new_token(:CONSTRUCTOR, :constructor)
742
800
  when input.scan(/noconstructor\b/)
743
- new_token(:NOCONSTRUCTOR, false)
801
+ new_token(:NOCONSTRUCTOR, :noconstructor)
744
802
  when input.scan(/\$\w+\b/)
745
803
  new_token(:GVAR, input.matched.to_sym)
746
804
  when input.scan(/[A-Z]\w*/)
@@ -753,7 +811,7 @@ def next_token
753
811
  new_token(:INT, input.matched.to_i)
754
812
  when input.scan(/\"[^\"]*\"/)
755
813
  new_token(:STRING, input.matched[1...-1])
756
- when input.scan(/\w+/)
757
- new_token(:IDENT, input.matched.to_sym)
814
+ when input.scan(/[a-z]\w*/)
815
+ new_token(:LIDENT, input.matched.to_sym)
758
816
  end
759
817
  end
data/lib/steep/source.rb CHANGED
@@ -33,9 +33,8 @@ module Steep
33
33
  value(token)
34
34
  end
35
35
 
36
- def emit_lambda
37
- true
38
- end
36
+ self.emit_lambda = true
37
+ self.emit_procarg0 = true
39
38
  end
40
39
 
41
40
  def self.parser
@@ -243,7 +242,7 @@ module Steep
243
242
 
244
243
  associated_annotations = annotations.select do |annot|
245
244
  case node.type
246
- when :def, :module, :class, :block, :ensure
245
+ when :def, :module, :class, :block, :ensure, :defs
247
246
  loc = node.loc
248
247
  loc.line <= annot.line && annot.line < loc.last_line
249
248
 
@@ -275,8 +274,8 @@ module Steep
275
274
  end
276
275
  end
277
276
 
278
- def annotations(block:)
279
- AST::Annotation::Collection.new(annotations: mapping[block.__id__] || [])
277
+ def annotations(block:, builder:, current_module:)
278
+ AST::Annotation::Collection.new(annotations: mapping[block.__id__] || [], builder: builder, current_module: current_module)
280
279
  end
281
280
 
282
281
  def each_annotation
@@ -39,6 +39,10 @@ module Steep
39
39
  end
40
40
  end
41
41
 
42
+ def alias?(type)
43
+ type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Alias)
44
+ end
45
+
42
46
  def cacheable?(relation)
43
47
  relation.sub_type.free_variables.empty? && relation.super_type.free_variables.empty?
44
48
  end
@@ -59,29 +63,33 @@ module Steep
59
63
  when relation.sub_type.is_a?(AST::Types::Any) || relation.super_type.is_a?(AST::Types::Any)
60
64
  success(constraints: constraints)
61
65
 
66
+ when relation.super_type.is_a?(AST::Types::Void)
67
+ success(constraints: constraints)
68
+
62
69
  when relation.super_type.is_a?(AST::Types::Top)
63
70
  success(constraints: constraints)
64
71
 
65
72
  when relation.sub_type.is_a?(AST::Types::Bot)
66
73
  success(constraints: constraints)
67
74
 
68
- when relation.super_type.is_a?(AST::Types::Var)
69
- if constraints.unknown?(relation.super_type.name)
70
- constraints.add(relation.super_type.name, sub_type: relation.sub_type)
71
- success(constraints: constraints)
72
- else
73
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
74
- trace: trace)
75
- end
75
+ when relation.super_type.is_a?(AST::Types::Boolean)
76
+ success(constraints: constraints)
76
77
 
77
- when relation.sub_type.is_a?(AST::Types::Var)
78
- if constraints.unknown?(relation.sub_type.name)
79
- constraints.add(relation.sub_type.name, super_type: relation.super_type)
80
- success(constraints: constraints)
81
- else
82
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
83
- trace: trace)
84
- end
78
+ when relation.sub_type.is_a?(AST::Types::Name) && relation.sub_type.name.is_a?(TypeName::Alias)
79
+ check0(
80
+ Relation.new(sub_type: expand_alias(relation.sub_type), super_type: relation.super_type),
81
+ assumption: assumption,
82
+ trace: trace,
83
+ constraints: constraints
84
+ )
85
+
86
+ when relation.super_type.is_a?(AST::Types::Name) && relation.super_type.name.is_a?(TypeName::Alias)
87
+ check0(
88
+ Relation.new(super_type: expand_alias(relation.super_type), sub_type: relation.sub_type),
89
+ assumption: assumption,
90
+ trace: trace,
91
+ constraints: constraints
92
+ )
85
93
 
86
94
  when relation.sub_type.is_a?(AST::Types::Literal)
87
95
  check0(
@@ -139,8 +147,27 @@ module Steep
139
147
  results.find(&:failure?)
140
148
  end
141
149
 
150
+ when relation.super_type.is_a?(AST::Types::Var)
151
+ if constraints.unknown?(relation.super_type.name)
152
+ constraints.add(relation.super_type.name, sub_type: relation.sub_type)
153
+ success(constraints: constraints)
154
+ else
155
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation),
156
+ trace: trace)
157
+ end
158
+
159
+ when relation.sub_type.is_a?(AST::Types::Var)
160
+ if constraints.unknown?(relation.sub_type.name)
161
+ constraints.add(relation.sub_type.name, super_type: relation.super_type)
162
+ success(constraints: constraints)
163
+ else
164
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation),
165
+ trace: trace)
166
+ end
167
+
142
168
  when relation.sub_type.is_a?(AST::Types::Name) && relation.super_type.is_a?(AST::Types::Name)
143
- if relation.sub_type.name == relation.super_type.name && relation.sub_type.args.size == relation.super_type.args.size
169
+ case
170
+ when relation.sub_type.name == relation.super_type.name && relation.sub_type.args.size == relation.super_type.args.size
144
171
  results = relation.sub_type.args.zip(relation.super_type.args).flat_map do |(sub, sup)|
145
172
  Relation.new(sub_type: sub, super_type: sup).yield_self do |rel|
146
173
  [rel, rel.flip]
@@ -164,9 +191,32 @@ module Steep
164
191
  check_interface(sub_interface, super_interface, assumption: assumption, trace: trace, constraints: constraints)
165
192
  end
166
193
 
194
+ when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
195
+ check_method_params(:__proc__,
196
+ relation.sub_type.params, relation.super_type.params,
197
+ assumption: assumption,
198
+ trace: trace,
199
+ constraints: constraints).then do
200
+ check0(Relation.new(sub_type: relation.sub_type.return_type, super_type: relation.super_type.return_type),
201
+ assumption: assumption,
202
+ trace: trace,
203
+ constraints: constraints)
204
+ end
205
+
167
206
  when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
168
- if relation.sub_type.types[0, relation.super_type.types.size] == relation.super_type.types
169
- success(constraints: constraints)
207
+ if relation.sub_type.types.size >= relation.super_type.types.size
208
+ pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
209
+ results = pairs.flat_map do |t1, t2|
210
+ relation = Relation.new(sub_type: t1, super_type: t2)
211
+ [check0(relation, assumption: assumption, trace: trace, constraints: constraints),
212
+ check0(relation.flip, assumption: assumption, trace: trace, constraints: constraints)]
213
+ end
214
+
215
+ if results.all?(&:success?)
216
+ success(constraints: constraints)
217
+ else
218
+ results.find(&:failure?)
219
+ end
170
220
  else
171
221
  failure(error: Result::Failure::UnknownPairError.new(relation: relation),
172
222
  trace: trace)
@@ -331,7 +381,9 @@ module Steep
331
381
  case
332
382
  when !super_block && !sub_block
333
383
  success(constraints: constraints)
334
- when super_block && sub_block
384
+ when super_block && sub_block && super_block.optional? == sub_block.optional?
385
+ success(constraints: constraints)
386
+ when sub_block&.optional?
335
387
  success(constraints: constraints)
336
388
  else
337
389
  failure(
@@ -371,10 +423,10 @@ module Steep
371
423
  # No block required and given
372
424
 
373
425
  when super_type.block && sub_type.block
374
- match_params(name, super_type.block.params, sub_type.block.params, trace: trace).yield_self do |block_result|
426
+ match_params(name, super_type.block.type.params, sub_type.block.type.params, trace: trace).yield_self do |block_result|
375
427
  return block_result unless block_result.is_a?(Array)
376
428
  pairs.push(*block_result)
377
- pairs.push [super_type.block.return_type, sub_type.block.return_type]
429
+ pairs.push [super_type.block.type.return_type, sub_type.block.type.return_type]
378
430
  end
379
431
 
380
432
  else
@@ -478,10 +530,10 @@ module Steep
478
530
  end
479
531
 
480
532
  def check_block_params(name, sub_block, super_block, assumption:, trace:, constraints:)
481
- if sub_block
533
+ if sub_block && super_block
482
534
  check_method_params(name,
483
- super_block.params,
484
- sub_block.params,
535
+ super_block.type.params,
536
+ sub_block.type.params,
485
537
  assumption: assumption,
486
538
  trace: trace,
487
539
  constraints: constraints)
@@ -491,9 +543,9 @@ module Steep
491
543
  end
492
544
 
493
545
  def check_block_return(sub_block, super_block, assumption:, trace:, constraints:)
494
- if sub_block
495
- relation = Relation.new(sub_type: super_block.return_type,
496
- super_type: sub_block.return_type)
546
+ if sub_block && super_block
547
+ relation = Relation.new(sub_type: super_block.type.return_type,
548
+ super_type: sub_block.type.return_type)
497
549
  check(relation, assumption: assumption, trace: trace, constraints: constraints)
498
550
  else
499
551
  success(constraints: constraints)
@@ -561,24 +613,29 @@ module Steep
561
613
  module_type: module_type,
562
614
  with_initialize: with_initialize)
563
615
  when AST::Types::Name
564
- builder.build(type.name, with_initialize: with_initialize).yield_self do |abstract|
565
- case type.name
566
- when TypeName::Instance, TypeName::Interface
567
- abstract.instantiate(
568
- type: self_type,
569
- args: type.args,
570
- instance_type: type,
571
- module_type: module_type || module_type(type)
572
- )
573
- when TypeName::Class, TypeName::Module
574
- signature = builder.signatures.find_class_or_module(type.name.name)
575
- args = signature.params&.variables&.map {|var| AST::Types::Var.new(name: var) } || []
576
- abstract.instantiate(
577
- type: self_type,
578
- args: [],
579
- instance_type: AST::Types::Name.new_instance(name: type.name.name, args: args),
580
- module_type: module_type || module_type(type)
581
- )
616
+ case type.name
617
+ when TypeName::Alias
618
+ resolve(expand_alias(type), self_type: self_type, instance_type: instance_type, module_type: module_type, with_initialize: with_initialize)
619
+ else
620
+ builder.build(type.name, with_initialize: with_initialize).yield_self do |abstract|
621
+ case type.name
622
+ when TypeName::Instance, TypeName::Interface
623
+ abstract.instantiate(
624
+ type: self_type,
625
+ args: type.args,
626
+ instance_type: type,
627
+ module_type: module_type || module_type(type)
628
+ )
629
+ when TypeName::Class, TypeName::Module
630
+ signature = builder.signatures.find_class_or_module(type.name.name)
631
+ args = signature.params&.variables&.map {|var| AST::Types::Var.new(name: var) } || []
632
+ abstract.instantiate(
633
+ type: self_type,
634
+ args: [],
635
+ instance_type: AST::Types::Name.new_instance(name: type.name.name, args: args),
636
+ module_type: module_type || module_type(type)
637
+ )
638
+ end
582
639
  end
583
640
  end
584
641
  when AST::Types::Union
@@ -691,9 +748,13 @@ module Steep
691
748
  end
692
749
  end
693
750
 
751
+ ivar_chains = interfaces.each.with_object({}) do |interface, chains|
752
+ chains.merge!(interface.ivar_chains)
753
+ end
754
+
694
755
  Interface::Instantiated.new(type: type,
695
756
  methods: methods,
696
- ivar_chains: {})
757
+ ivar_chains: ivar_chains)
697
758
  when AST::Types::Void
698
759
  Interface::Instantiated.new(type: type,
699
760
  methods: {},
@@ -744,6 +805,60 @@ module Steep
744
805
 
745
806
  array_interface
746
807
  end
808
+
809
+ when AST::Types::Proc
810
+ yield_self do
811
+ proc_interface = resolve(type.back_type, self_type: self_type, with_initialize: with_initialize)
812
+ apply_type = Interface::MethodType.new(
813
+ type_params: [],
814
+ params: type.params,
815
+ block: nil,
816
+ return_type: type.return_type,
817
+ location: nil
818
+ )
819
+
820
+ proc_interface.methods[:[]] = proc_interface.methods[:[]].yield_self do |aref|
821
+ aref.with_types([apply_type])
822
+ end
823
+ proc_interface.methods[:call] = proc_interface.methods[:call].yield_self do |aref|
824
+ aref.with_types([apply_type])
825
+ end
826
+
827
+ proc_interface
828
+ end
829
+
830
+ end
831
+ end
832
+
833
+ def expand_alias(type)
834
+ expanded = case type
835
+ when AST::Types::Union
836
+ AST::Types::Union.build(
837
+ types: type.types.map {|ty| expand_alias(ty) },
838
+ location: type.location
839
+ )
840
+ when AST::Types::Intersection
841
+ AST::Types::Intersection.build(
842
+ types: type.types.map {|ty| expand_alias(ty) },
843
+ location: type.location
844
+ )
845
+ when AST::Types::Name
846
+ if type.name.is_a?(TypeName::Alias)
847
+ a = builder.signatures.find_alias(type.name.name) or raise "Unknown alias name: #{type.name.name}"
848
+ args = type.args.map {|ty| expand_alias(ty) }
849
+ s = Interface::Substitution.build(a.params&.variables || [], args)
850
+ expand_alias(a.type.subst(s))
851
+ else
852
+ type
853
+ end
854
+ else
855
+ type
856
+ end
857
+
858
+ if block_given?
859
+ yield expanded
860
+ else
861
+ expanded
747
862
  end
748
863
  end
749
864
  end
@@ -20,12 +20,12 @@ module Steep
20
20
  end
21
21
 
22
22
  method_type.block&.yield_self do |block|
23
- block.params.each_type do |type|
23
+ block.type.params.each_type do |type|
24
24
  each_var(type) do |var|
25
25
  params << var
26
26
  end
27
27
  end
28
- each_var(block.return_type) do |var|
28
+ each_var(block.type.return_type) do |var|
29
29
  returns << var
30
30
  end
31
31
  end
@@ -28,9 +28,9 @@ module Steep
28
28
  add_params(method_type.params, block: false, contravariants: contravariants, covariants: covariants)
29
29
  add_type(method_type.return_type, variance: :covariant, covariants: covariants, contravariants: contravariants)
30
30
 
31
- method_type.block&.yield_self do |block|
32
- add_params(block.params, block: true, contravariants: contravariants, covariants: covariants)
33
- add_type(block.return_type, variance: :contravariant, covariants: covariants, contravariants: contravariants)
31
+ method_type.block&.type&.yield_self do |proc|
32
+ add_params(proc.params, block: true, contravariants: contravariants, covariants: covariants)
33
+ add_type(proc.return_type, variance: :contravariant, covariants: covariants, contravariants: contravariants)
34
34
  end
35
35
 
36
36
  new(covariants: covariants, contravariants: contravariants)