steep 0.4.0 → 0.5.0

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