steep 0.47.1 → 0.49.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Gemfile.lock +7 -7
  4. data/lib/steep/ast/types/any.rb +2 -0
  5. data/lib/steep/ast/types/boolean.rb +2 -0
  6. data/lib/steep/ast/types/bot.rb +2 -0
  7. data/lib/steep/ast/types/class.rb +2 -0
  8. data/lib/steep/ast/types/factory.rb +162 -138
  9. data/lib/steep/ast/types/helper.rb +8 -0
  10. data/lib/steep/ast/types/instance.rb +2 -0
  11. data/lib/steep/ast/types/intersection.rb +4 -0
  12. data/lib/steep/ast/types/literal.rb +2 -0
  13. data/lib/steep/ast/types/logic.rb +2 -0
  14. data/lib/steep/ast/types/name.rb +6 -0
  15. data/lib/steep/ast/types/nil.rb +2 -0
  16. data/lib/steep/ast/types/proc.rb +9 -0
  17. data/lib/steep/ast/types/record.rb +4 -0
  18. data/lib/steep/ast/types/self.rb +2 -0
  19. data/lib/steep/ast/types/top.rb +2 -0
  20. data/lib/steep/ast/types/tuple.rb +4 -0
  21. data/lib/steep/ast/types/union.rb +4 -0
  22. data/lib/steep/ast/types/var.rb +16 -3
  23. data/lib/steep/ast/types/void.rb +2 -0
  24. data/lib/steep/diagnostic/ruby.rb +36 -11
  25. data/lib/steep/diagnostic/signature.rb +56 -0
  26. data/lib/steep/drivers/check.rb +2 -2
  27. data/lib/steep/interface/function.rb +4 -0
  28. data/lib/steep/interface/method_type.rb +14 -26
  29. data/lib/steep/interface/type_param.rb +103 -0
  30. data/lib/steep/server/base_worker.rb +1 -0
  31. data/lib/steep/server/interaction_worker.rb +1 -1
  32. data/lib/steep/server/type_check_worker.rb +2 -2
  33. data/lib/steep/services/signature_service.rb +2 -2
  34. data/lib/steep/services/type_check_service.rb +4 -1
  35. data/lib/steep/signature/validator.rb +228 -49
  36. data/lib/steep/subtyping/cache.rb +30 -0
  37. data/lib/steep/subtyping/check.rb +600 -705
  38. data/lib/steep/subtyping/constraints.rb +66 -30
  39. data/lib/steep/subtyping/relation.rb +60 -0
  40. data/lib/steep/subtyping/result.rb +190 -16
  41. data/lib/steep/type_construction.rb +576 -395
  42. data/lib/steep/type_inference/block_params.rb +31 -3
  43. data/lib/steep/type_inference/context.rb +37 -3
  44. data/lib/steep/version.rb +1 -1
  45. data/lib/steep.rb +3 -3
  46. data/sample/lib/length.rb +35 -0
  47. data/sample/sig/length.rbs +34 -0
  48. data/smoke/diagnostics/proc_type_expected.rb +3 -0
  49. data/smoke/diagnostics/test_expectations.yml +12 -0
  50. data/smoke/diagnostics-rbs/nonregular-type-alias.rbs +3 -0
  51. data/smoke/diagnostics-rbs/recursive-type-alias.rbs +3 -0
  52. data/smoke/diagnostics-rbs/test_expectations.yml +57 -12
  53. data/smoke/tsort/a.rb +1 -1
  54. data/smoke/tsort/test_expectations.yml +1 -63
  55. data/steep.gemspec +1 -1
  56. metadata +14 -10
  57. data/lib/steep/drivers/trace_printer.rb +0 -29
  58. data/lib/steep/interface/method.rb +0 -78
  59. data/lib/steep/subtyping/trace.rb +0 -71
@@ -3,10 +3,78 @@ module Steep
3
3
  class Check
4
4
  attr_reader :factory
5
5
  attr_reader :cache
6
+ attr_reader :assumptions
6
7
 
7
8
  def initialize(factory:)
8
9
  @factory = factory
9
- @cache = {}
10
+ @cache = Cache.new()
11
+ @bounds = []
12
+ end
13
+
14
+ def with_context(self_type:, instance_type:, class_type:, constraints:)
15
+ @self_type = self_type
16
+ @instance_type = instance_type
17
+ @class_type = class_type
18
+ @constraints = constraints
19
+ @assumptions = Set[]
20
+
21
+ yield
22
+ ensure
23
+ @self_type = nil
24
+ @instance_type = nil
25
+ @class_type = nil
26
+ @constraints = nil
27
+ @assumptions = nil
28
+ end
29
+
30
+ def push_assumption(relation)
31
+ assumptions << relation
32
+ yield
33
+ ensure
34
+ assumptions.delete(relation)
35
+ end
36
+
37
+ def push_variable_bounds(params)
38
+ case params
39
+ when Array
40
+ b = params.each.with_object({}) do |param, hash|
41
+ hash[param.name] = param.upper_bound
42
+ end
43
+ when Hash
44
+ b = params
45
+ end
46
+
47
+ @bounds.push(b)
48
+ yield
49
+
50
+ ensure
51
+ @bounds.pop
52
+ end
53
+
54
+ def variable_upper_bound(name)
55
+ @bounds.reverse_each do |hash|
56
+ if hash.key?(name)
57
+ return hash[name]
58
+ end
59
+ end
60
+
61
+ nil
62
+ end
63
+
64
+ def self_type
65
+ @self_type || raise
66
+ end
67
+
68
+ def instance_type
69
+ @instance_type || raise
70
+ end
71
+
72
+ def class_type
73
+ @class_type || raise
74
+ end
75
+
76
+ def constraints
77
+ @constraints || raise
10
78
  end
11
79
 
12
80
  def each_ancestor(ancestors, &block)
@@ -98,42 +166,44 @@ module Steep
98
166
  end
99
167
  end
100
168
 
101
- def check(relation, constraints:, self_type:, instance_type:, class_type:, assumption: Set.new, trace: Trace.new)
169
+ def check(relation, constraints:, self_type:, instance_type:, class_type:)
170
+ with_context(self_type: self_type, instance_type: instance_type, class_type: class_type, constraints: constraints) do
171
+ check_type(relation)
172
+ end
173
+ end
174
+
175
+ def check_type(relation)
176
+ relation.type!
177
+
102
178
  Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
103
- prefix = trace.size
104
- cached = cache[[relation, self_type, instance_type, class_type]]
179
+ bounds = cache_bounds(relation)
180
+ cached = cache[relation, @self_type, @instance_type, @class_type, bounds]
105
181
  if cached && constraints.empty?
106
- if cached.success?
107
- cached
108
- else
109
- cached.merge_trace(trace)
110
- end
182
+ cached
111
183
  else
112
- if assumption.member?(relation)
113
- success(constraints: constraints)
184
+ if assumptions.member?(relation)
185
+ success(relation)
114
186
  else
115
- assumption = assumption + Set[relation]
116
- check0(
117
- relation,
118
- self_type: self_type,
119
- instance_type: instance_type,
120
- class_type: class_type,
121
- assumption: assumption,
122
- trace: trace,
123
- constraints: constraints
124
- ).tap do |result|
125
- result = result.else do |failure|
126
- failure.drop(prefix)
187
+ push_assumption(relation) do
188
+ check_type0(relation).tap do |result|
189
+ Steep.logger.debug "result=#{result.class}"
190
+ cache[relation, @self_type, @instance_type, @class_type, bounds] = result
127
191
  end
128
-
129
- Steep.logger.debug "result=#{result.class}"
130
- cache[[relation, self_type]] = result if cacheable?(relation)
131
192
  end
132
193
  end
133
194
  end
134
195
  end
135
196
  end
136
197
 
198
+ def cache_bounds(relation)
199
+ vars = relation.sub_type.free_variables + relation.super_type.free_variables
200
+ vars.each.with_object({}) do |var, hash|
201
+ if upper_bound = variable_upper_bound(var)
202
+ hash[var] = upper_bound
203
+ end
204
+ end
205
+ end
206
+
137
207
  def alias?(type)
138
208
  type.is_a?(AST::Types::Name::Alias)
139
209
  end
@@ -142,14 +212,6 @@ module Steep
142
212
  relation.sub_type.free_variables.empty? && relation.super_type.free_variables.empty?
143
213
  end
144
214
 
145
- def success(constraints:)
146
- Result::Success.new(constraints: constraints)
147
- end
148
-
149
- def failure(error:, trace:)
150
- Result::Failure.new(error: error, trace: trace)
151
- end
152
-
153
215
  def true_type?(type)
154
216
  case type
155
217
  when AST::Types::Literal
@@ -168,403 +230,285 @@ module Steep
168
230
  end
169
231
  end
170
232
 
171
- def check0(relation, self_type:, class_type:, instance_type:, assumption:, trace:, constraints:)
172
- # puts relation
173
- trace.type(relation.sub_type, relation.super_type) do
174
- case
175
- when same_type?(relation, assumption: assumption)
176
- success(constraints: constraints)
233
+ include Result::Helper
177
234
 
178
- when relation.sub_type.is_a?(AST::Types::Any) || relation.super_type.is_a?(AST::Types::Any)
179
- success(constraints: constraints)
235
+ def check_type0(relation)
236
+ case
237
+ when same_type?(relation)
238
+ success(relation)
180
239
 
181
- when relation.super_type.is_a?(AST::Types::Void)
182
- success(constraints: constraints)
240
+ when relation.sub_type.is_a?(AST::Types::Any) || relation.super_type.is_a?(AST::Types::Any)
241
+ success(relation)
183
242
 
184
- when relation.super_type.is_a?(AST::Types::Top)
185
- success(constraints: constraints)
243
+ when relation.super_type.is_a?(AST::Types::Void)
244
+ success(relation)
186
245
 
187
- when relation.sub_type.is_a?(AST::Types::Bot)
188
- success(constraints: constraints)
246
+ when relation.super_type.is_a?(AST::Types::Top)
247
+ success(relation)
189
248
 
190
- when relation.sub_type.is_a?(AST::Types::Logic::Base) && (true_type?(relation.super_type) || false_type?(relation.super_type))
191
- success(constraints: constraints)
249
+ when relation.sub_type.is_a?(AST::Types::Bot)
250
+ success(relation)
192
251
 
193
- when relation.super_type.is_a?(AST::Types::Boolean)
194
- check(
195
- Relation.new(sub_type: relation.sub_type, super_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type])),
196
- self_type: self_type,
197
- instance_type: instance_type,
198
- class_type: class_type,
199
- assumption: assumption,
200
- trace: trace,
201
- constraints: constraints
202
- )
252
+ when relation.sub_type.is_a?(AST::Types::Logic::Base) && (true_type?(relation.super_type) || false_type?(relation.super_type))
253
+ success(relation)
203
254
 
204
- when relation.sub_type.is_a?(AST::Types::Boolean)
205
- check(
206
- Relation.new(sub_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type]),
207
- super_type: relation.super_type),
208
- self_type: self_type,
209
- instance_type: instance_type,
210
- class_type: class_type,
211
- assumption: assumption,
212
- trace: trace,
213
- constraints: constraints
255
+ when relation.super_type.is_a?(AST::Types::Boolean)
256
+ Expand(relation) do
257
+ check_type(
258
+ Relation.new(
259
+ sub_type: relation.sub_type,
260
+ super_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type])
261
+ )
214
262
  )
263
+ end
215
264
 
216
- when relation.sub_type.is_a?(AST::Types::Self) && !self_type.is_a?(AST::Types::Self)
217
- check(
218
- Relation.new(sub_type: self_type, super_type: relation.super_type),
219
- self_type: self_type,
220
- instance_type: instance_type,
221
- class_type: class_type,
222
- assumption: assumption,
223
- trace: trace,
224
- constraints: constraints
265
+ when relation.sub_type.is_a?(AST::Types::Boolean)
266
+ Expand(relation) do
267
+ check_type(
268
+ Relation.new(
269
+ sub_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type]),
270
+ super_type: relation.super_type
271
+ )
225
272
  )
273
+ end
226
274
 
227
- when relation.sub_type.is_a?(AST::Types::Instance) && !instance_type.is_a?(AST::Types::Instance)
228
- check(
229
- Relation.new(sub_type: instance_type, super_type: relation.super_type),
230
- self_type: self_type,
231
- instance_type: instance_type,
232
- class_type: class_type,
233
- assumption: assumption,
234
- trace: trace,
235
- constraints: constraints
236
- )
275
+ when relation.sub_type.is_a?(AST::Types::Self) && !self_type.is_a?(AST::Types::Self)
276
+ Expand(relation) do
277
+ check_type(Relation.new(sub_type: self_type, super_type: relation.super_type))
278
+ end
237
279
 
238
- when relation.super_type.is_a?(AST::Types::Instance) && !instance_type.is_a?(AST::Types::Instance)
239
- rel = Relation.new(sub_type: relation.sub_type, super_type: instance_type)
280
+ when relation.sub_type.is_a?(AST::Types::Instance) && !instance_type.is_a?(AST::Types::Instance)
281
+ Expand(relation) do
282
+ check_type(Relation.new(sub_type: instance_type, super_type: relation.super_type))
283
+ end
240
284
 
241
- success_all?([rel, rel.flip]) do |r|
242
- check(
243
- r,
244
- self_type: self_type,
245
- instance_type: instance_type,
246
- class_type: class_type,
247
- assumption: assumption,
248
- trace: trace,
249
- constraints: constraints
250
- )
251
- end.then do |result|
252
- Steep.logger.error { "`T <: instance` doesn't hold generally, but testing it with `#{relation} && #{relation.flip}` for compatibility"}
253
- result
285
+ when relation.super_type.is_a?(AST::Types::Instance) && !instance_type.is_a?(AST::Types::Instance)
286
+ All(relation) do |result|
287
+ rel = Relation.new(sub_type: relation.sub_type, super_type: instance_type)
288
+ result.add(rel, rel.flip) do |r|
289
+ check_type(r)
254
290
  end
291
+ end.tap do
292
+ Steep.logger.error { "`T <: instance` doesn't hold generally, but testing it with `#{relation} && #{relation.flip}` for compatibility"}
293
+ end
255
294
 
256
- when relation.sub_type.is_a?(AST::Types::Class) && !instance_type.is_a?(AST::Types::Class)
257
- check(
258
- Relation.new(sub_type: class_type, super_type: relation.super_type),
259
- self_type: self_type,
260
- instance_type: instance_type,
261
- class_type: class_type,
262
- assumption: assumption,
263
- trace: trace,
264
- constraints: constraints
265
- )
295
+ when relation.sub_type.is_a?(AST::Types::Class) && !instance_type.is_a?(AST::Types::Class)
296
+ Expand(relation) do
297
+ check_type(Relation.new(sub_type: class_type, super_type: relation.super_type))
298
+ end
266
299
 
267
- when relation.super_type.is_a?(AST::Types::Class) && !instance_type.is_a?(AST::Types::Class)
300
+ when relation.super_type.is_a?(AST::Types::Class) && !instance_type.is_a?(AST::Types::Class)
301
+ All(relation) do |result|
268
302
  rel = Relation.new(sub_type: relation.sub_type, super_type: class_type)
269
-
270
- success_all?([rel, rel.flip]) do |r|
271
- check(
272
- r,
273
- self_type: self_type,
274
- instance_type: instance_type,
275
- class_type: class_type,
276
- assumption: assumption,
277
- trace: trace,
278
- constraints: constraints
279
- )
280
- end.then do |result|
281
- Steep.logger.error { "`T <: class` doesn't hold generally, but testing with `#{relation} && |- #{relation.flip}` for compatibility"}
282
- result
303
+ result.add(rel, rel.flip) do |r|
304
+ check_type(r)
283
305
  end
306
+ end.tap do
307
+ Steep.logger.error { "`T <: class` doesn't hold generally, but testing with `#{relation} && |- #{relation.flip}` for compatibility"}
308
+ end
284
309
 
285
- when alias?(relation.sub_type)
286
- check(
287
- Relation.new(sub_type: expand_alias(relation.sub_type), super_type: relation.super_type),
288
- self_type: self_type,
289
- instance_type: instance_type,
290
- class_type: class_type,
291
- assumption: assumption,
292
- trace: trace,
293
- constraints: constraints
294
- )
310
+ when alias?(relation.sub_type)
311
+ Expand(relation) do
312
+ check_type(Relation.new(sub_type: expand_alias(relation.sub_type), super_type: relation.super_type))
313
+ end
295
314
 
296
- when alias?(relation.super_type)
297
- check(
298
- Relation.new(super_type: expand_alias(relation.super_type), sub_type: relation.sub_type),
299
- self_type: self_type,
300
- instance_type: instance_type,
301
- class_type: class_type,
302
- assumption: assumption,
303
- trace: trace,
304
- constraints: constraints
305
- )
315
+ when alias?(relation.super_type)
316
+ Expand(relation) do
317
+ check_type(Relation.new(super_type: expand_alias(relation.super_type), sub_type: relation.sub_type))
318
+ end
306
319
 
307
- when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
308
- constraints.add(relation.super_type.name, sub_type: relation.sub_type)
309
- success(constraints: constraints)
310
-
311
- when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
312
- constraints.add(relation.sub_type.name, super_type: relation.super_type)
313
- success(constraints: constraints)
314
-
315
- when relation.sub_type.is_a?(AST::Types::Union)
316
- results = relation.sub_type.types.map do |sub_type|
317
- check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
318
- self_type: self_type,
319
- instance_type: instance_type,
320
- class_type: class_type,
321
- assumption: assumption,
322
- trace: trace,
323
- constraints: constraints)
320
+ when relation.super_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.super_type.name)
321
+ if ub = variable_upper_bound(relation.super_type.name)
322
+ Expand(relation) do
323
+ check_type(Relation.new(sub_type: relation.sub_type, super_type: ub))
324
+ end.tap do |result|
325
+ if result.success?
326
+ constraints.add(relation.super_type.name, sub_type: relation.sub_type)
327
+ end
324
328
  end
329
+ else
330
+ constraints.add(relation.super_type.name, sub_type: relation.sub_type)
331
+ Success(relation)
332
+ end
325
333
 
326
- if results.all?(&:success?)
327
- results.first
328
- else
329
- results.find(&:failure?)
334
+ when relation.sub_type.is_a?(AST::Types::Var) && constraints.unknown?(relation.sub_type.name)
335
+ constraints.add(relation.sub_type.name, super_type: relation.super_type)
336
+ Success(relation)
337
+
338
+ when relation.sub_type.is_a?(AST::Types::Union)
339
+ All(relation) do |result|
340
+ relation.sub_type.types.each do |sub_type|
341
+ rel = Relation.new(sub_type: sub_type, super_type: relation.super_type)
342
+ result.add(rel) do
343
+ check_type(rel)
344
+ end
330
345
  end
346
+ end
331
347
 
332
- when relation.super_type.is_a?(AST::Types::Union)
333
- results = relation.super_type.types.map do |super_type|
334
- check(Relation.new(sub_type: relation.sub_type, super_type: super_type),
335
- self_type: self_type,
336
- instance_type: instance_type,
337
- class_type: class_type,
338
- assumption: assumption,
339
- trace: trace,
340
- constraints: constraints)
348
+ when relation.super_type.is_a?(AST::Types::Union)
349
+ Any(relation) do |result|
350
+ relation.super_type.types.sort_by {|ty| (path = hole_path(ty)) ? -path.size : 1 }.each do |super_type|
351
+ rel = Relation.new(sub_type: relation.sub_type, super_type: super_type)
352
+ result.add(rel) do
353
+ check_type(rel)
354
+ end
341
355
  end
356
+ end
342
357
 
343
- results.find(&:success?) || results.first
344
-
345
- when relation.sub_type.is_a?(AST::Types::Intersection)
346
- results = relation.sub_type.types.map do |sub_type|
347
- check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
348
- self_type: self_type,
349
- instance_type: instance_type,
350
- class_type: class_type,
351
- assumption: assumption,
352
- trace: trace,
353
- constraints: constraints)
358
+ when relation.sub_type.is_a?(AST::Types::Intersection)
359
+ Any(relation) do |result|
360
+ relation.sub_type.types.sort_by {|ty| (path = hole_path(ty)) ? -path.size : 1 }.each do |sub_type|
361
+ rel = Relation.new(sub_type: sub_type, super_type: relation.super_type)
362
+ result.add(rel) do
363
+ check_type(rel)
364
+ end
354
365
  end
366
+ end
355
367
 
356
- results.find(&:success?) || results.first
357
-
358
- when relation.super_type.is_a?(AST::Types::Intersection)
359
- results = relation.super_type.types.map do |super_type|
360
- check(Relation.new(sub_type: relation.sub_type, super_type: super_type),
361
- self_type: self_type,
362
- instance_type: instance_type,
363
- class_type: class_type,
364
- assumption: assumption,
365
- trace: trace,
366
- constraints: constraints)
368
+ when relation.super_type.is_a?(AST::Types::Intersection)
369
+ All(relation) do |result|
370
+ relation.super_type.types.each do |super_type|
371
+ result.add(Relation.new(sub_type: relation.sub_type, super_type: super_type)) do |rel|
372
+ check_type(rel)
373
+ end
367
374
  end
375
+ end
376
+
377
+ when relation.sub_type.is_a?(AST::Types::Var) && ub = variable_upper_bound(relation.sub_type.name)
378
+ Expand(relation) do
379
+ check_type(Relation.new(sub_type: ub, super_type: relation.super_type))
380
+ end
381
+
382
+ when relation.super_type.is_a?(AST::Types::Var) || relation.sub_type.is_a?(AST::Types::Var)
383
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
368
384
 
369
- if results.all?(&:success?)
370
- results.first
385
+ when relation.super_type.is_a?(AST::Types::Name::Interface)
386
+ Expand(relation) do
387
+ check_interface(relation.map {|type| factory.interface(type, private: false) })
388
+ end
389
+
390
+ when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
391
+ if relation.sub_type.name == relation.super_type.name && relation.sub_type.class == relation.super_type.class
392
+ if arg_type?(relation.sub_type) && arg_type?(relation.super_type)
393
+ check_type_arg(relation)
371
394
  else
372
- results.find(&:failure?)
395
+ Success(relation)
373
396
  end
374
-
375
- when relation.super_type.is_a?(AST::Types::Var) || relation.sub_type.is_a?(AST::Types::Var)
376
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
377
- trace: trace)
378
-
379
- when relation.super_type.is_a?(AST::Types::Name::Interface)
380
- sub_interface = factory.interface(relation.sub_type, private: false)
381
- super_interface = factory.interface(relation.super_type, private: false)
382
-
383
- check_interface(sub_interface,
384
- super_interface,
385
- self_type: self_type,
386
- instance_type: instance_type,
387
- class_type: class_type,
388
- assumption: assumption,
389
- trace: trace,
390
- constraints: constraints)
391
-
392
- when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
393
- if relation.sub_type.name == relation.super_type.name && relation.sub_type.class == relation.super_type.class
394
- if arg_type?(relation.sub_type) && arg_type?(relation.super_type)
395
- check_type_arg(
396
- relation,
397
- self_type: self_type,
398
- instance_type: instance_type,
399
- class_type: class_type,
400
- assumption: assumption,
401
- trace: trace,
402
- constraints: constraints
403
- )
397
+ else
398
+ possible_sub_types =
399
+ case relation.sub_type
400
+ when AST::Types::Name::Instance
401
+ instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
402
+ when AST::Types::Name::Singleton
403
+ singleton_super_types(relation.sub_type.name)
404
404
  else
405
- success(constraints: constraints)
405
+ []
406
406
  end
407
- else
408
- possible_sub_types = case relation.sub_type
409
- when AST::Types::Name::Instance
410
- instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
411
- when AST::Types::Name::Singleton
412
- singleton_super_types(relation.sub_type.name)
413
- else
414
- []
415
- end
416
-
417
- unless possible_sub_types.empty?
418
- success_any?(possible_sub_types) do |sub_type|
419
- check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
420
- self_type: self_type,
421
- instance_type: instance_type,
422
- class_type: class_type,
423
- assumption: assumption,
424
- trace: trace,
425
- constraints: constraints)
407
+
408
+ unless possible_sub_types.empty?
409
+ Any(relation) do |result|
410
+ possible_sub_types.each do |sub_type|
411
+ result.add(Relation.new(sub_type: sub_type, super_type: relation.super_type)) do |rel|
412
+ check_type(rel)
413
+ end
426
414
  end
427
- else
428
- failure(error: Result::Failure::UnknownPairError.new(relation: relation), trace: trace)
429
415
  end
416
+ else
417
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
430
418
  end
419
+ end
431
420
 
432
- when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
433
- name = :__proc__
434
-
435
- sub_type = relation.sub_type
436
- super_type = relation.super_type
437
-
438
- check_method_params(name, sub_type.type.params, super_type.type.params, self_type: self_type, instance_type: instance_type, class_type: class_type, assumption: assumption, trace: trace, constraints: constraints).then do
439
- check_block_given(name, sub_type.block, super_type.block, trace: trace, constraints: constraints).then do
440
- check_block_params(name, sub_type.block, super_type.block, self_type: self_type, instance_type: instance_type, class_type: class_type, assumption: assumption, trace: trace, constraints: constraints).then do
441
- check_block_return(sub_type.block, super_type.block, self_type: self_type, instance_type: instance_type, class_type: class_type, assumption: assumption, trace: trace, constraints:constraints).then do
442
- relation = Relation.new(super_type: super_type.type.return_type, sub_type: sub_type.type.return_type)
443
- check(
444
- relation,
445
- self_type: self_type,
446
- instance_type: instance_type,
447
- class_type: class_type,
448
- assumption: assumption,
449
- trace: trace,
450
- constraints: constraints
451
- )
452
- end
421
+ when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
422
+ name = :__proc__
423
+
424
+ sub_type = relation.sub_type
425
+ super_type = relation.super_type
426
+
427
+ All(relation) do |result|
428
+ result.add(relation.map {|p| p.type }) do |rel|
429
+ check_function(name, rel)
430
+ end
431
+
432
+ result.add(relation.map {|p| p.block }) do |rel|
433
+ check_block_given(name, rel) do
434
+ Expand(rel.map {|b| b.type }) do |rel|
435
+ check_function(name, rel.flip)
453
436
  end
454
437
  end
455
438
  end
439
+ end
456
440
 
457
- when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
458
- if relation.sub_type.types.size >= relation.super_type.types.size
459
- pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
460
- results = pairs.map do |t1, t2|
461
- relation = Relation.new(sub_type: t1, super_type: t2)
462
- check(
463
- relation,
464
- self_type: self_type,
465
- instance_type: instance_type,
466
- class_type: class_type,
467
- assumption: assumption,
468
- trace: trace,
469
- constraints: constraints
470
- )
471
- end
441
+ when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
442
+ if relation.sub_type.types.size >= relation.super_type.types.size
443
+ pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
472
444
 
473
- if results.all?(&:success?)
474
- success(constraints: constraints)
475
- else
476
- results.find(&:failure?)
445
+ All(relation) do |result|
446
+ pairs.each do |t1, t2|
447
+ result.add(Relation.new(sub_type: t1, super_type: t2)) do |rel|
448
+ check_type(rel)
449
+ end
477
450
  end
478
- else
479
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
480
- trace: trace)
481
451
  end
452
+ else
453
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
454
+ end
482
455
 
483
- when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
484
- tuple_element_type = AST::Types::Union.build(
485
- types: relation.sub_type.types,
486
- location: relation.sub_type.location
487
- )
456
+ when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
457
+ Expand(relation) do
458
+ tuple_element_type =
459
+ AST::Types::Union.build(
460
+ types: relation.sub_type.types,
461
+ location: relation.sub_type.location
462
+ )
488
463
 
489
- check(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]),
490
- self_type: self_type,
491
- instance_type: instance_type,
492
- class_type: class_type,
493
- assumption: assumption,
494
- trace: trace,
495
- constraints: constraints)
496
-
497
- when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
498
- keys = relation.super_type.elements.keys
499
- relations = keys.map {|key|
500
- Relation.new(
464
+ check_type(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]))
465
+ end
466
+
467
+ when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
468
+ All(relation) do |result|
469
+ relation.super_type.elements.each_key do |key|
470
+ rel = Relation.new(
501
471
  sub_type: relation.sub_type.elements[key] || AST::Builtin.nil_type,
502
472
  super_type: relation.super_type.elements[key]
503
473
  )
504
- }
505
- results = relations.map do |relation|
506
- check(
507
- relation,
508
- self_type: self_type,
509
- instance_type: instance_type,
510
- class_type: class_type,
511
- assumption: assumption,
512
- trace: trace,
513
- constraints: constraints
514
- )
515
- end
516
474
 
517
- if results.all?(&:success?)
518
- success(constraints: constraints)
519
- else
520
- results.find(&:failure?)
475
+ result.add(rel) do
476
+ check_type(rel)
477
+ end
521
478
  end
479
+ end
522
480
 
523
- when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Name::Base)
524
- record_interface = factory.interface(relation.sub_type, private: false)
525
- type_interface = factory.interface(relation.super_type, private: false)
526
-
527
- check_interface(record_interface,
528
- type_interface,
529
- self_type: self_type,
530
- instance_type: instance_type,
531
- class_type: class_type,
532
- assumption: assumption,
533
- trace: trace,
534
- constraints: constraints)
535
-
536
- when relation.super_type.is_a?(AST::Types::Literal)
537
- case
538
- when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
539
- success(constraints: constraints)
540
- when relation.super_type.value == false && AST::Builtin::FalseClass.instance_type?(relation.sub_type)
541
- success(constraints: constraints)
542
- else
543
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
544
- trace: trace)
545
- end
481
+ when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Name::Base)
482
+ Expand(relation) do
483
+ check_interface(relation.map {|type| factory.interface(type, private: false) })
484
+ end
546
485
 
547
- when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
548
- success(constraints: constraints)
549
-
550
- when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
551
- success(constraints: constraints)
552
-
553
- when relation.sub_type.is_a?(AST::Types::Literal)
554
- check(
555
- Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
556
- self_type: self_type,
557
- instance_type: instance_type,
558
- class_type: class_type,
559
- assumption: assumption,
560
- trace: trace,
561
- constraints: constraints
562
- )
486
+ when relation.sub_type.is_a?(AST::Types::Proc) && AST::Builtin::Proc.instance_type?(relation.super_type)
487
+ Success(relation)
563
488
 
489
+ when relation.super_type.is_a?(AST::Types::Literal)
490
+ case
491
+ when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
492
+ Success(relation)
493
+ when relation.super_type.value == false && AST::Builtin::FalseClass.instance_type?(relation.sub_type)
494
+ Success(relation)
564
495
  else
565
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
566
- trace: trace)
496
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
497
+ end
498
+
499
+ when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
500
+ Success(relation)
501
+
502
+ when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
503
+ Success(relation)
504
+
505
+ when relation.sub_type.is_a?(AST::Types::Literal)
506
+ Expand(relation) do
507
+ check_type(Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type))
567
508
  end
509
+
510
+ else
511
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
568
512
  end
569
513
  end
570
514
 
@@ -592,390 +536,357 @@ module Steep
592
536
  end
593
537
  end
594
538
 
595
- def check_type_arg(relation, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
539
+ def check_type_arg(relation)
596
540
  sub_args = relation.sub_type.args
597
541
  sup_args = relation.super_type.args
598
542
 
599
543
  sup_def = definition_for_type(relation.super_type)
600
544
  sup_params = sup_def.type_params_decl
601
545
 
602
- success_all?(sub_args.zip(sup_args, sup_params.each)) do |sub_arg, sup_arg, sup_param|
603
- case sup_param.variance
604
- when :covariant
605
- check(
606
- Relation.new(sub_type: sub_arg, super_type: sup_arg),
607
- self_type: self_type,
608
- instance_type: instance_type,
609
- class_type: class_type,
610
- assumption: assumption,
611
- trace: trace,
612
- constraints: constraints
613
- )
614
- when :contravariant
615
- check(
616
- Relation.new(sub_type: sup_arg, super_type: sub_arg),
617
- self_type: self_type,
618
- instance_type: instance_type,
619
- class_type: class_type,
620
- assumption: assumption,
621
- trace: trace,
622
- constraints: constraints
623
- )
624
- when :invariant
625
- rel = Relation.new(sub_type: sub_arg, super_type: sup_arg)
626
- success_all?([rel, rel.flip]) do |r|
627
- check(
628
- r,
629
- self_type: self_type,
630
- instance_type: instance_type,
631
- class_type: class_type,
632
- assumption: assumption,
633
- trace: trace,
634
- constraints: constraints
635
- )
546
+ All(relation) do |result|
547
+ sub_args.zip(sup_args, sup_params.each).each do |sub_arg, sup_arg, sup_param|
548
+ case sup_param.variance
549
+ when :covariant
550
+ result.add(Relation.new(sub_type: sub_arg, super_type: sup_arg)) do |rel|
551
+ check_type(rel)
552
+ end
553
+ when :contravariant
554
+ result.add(Relation.new(sub_type: sup_arg, super_type: sub_arg)) do |rel|
555
+ check_type(rel)
556
+ end
557
+ when :invariant
558
+ rel = Relation.new(sub_type: sub_arg, super_type: sup_arg)
559
+ result.add(rel, rel.flip) do |rel|
560
+ check_type(rel)
561
+ end
636
562
  end
637
563
  end
638
564
  end
639
565
  end
640
566
 
641
- def success_all?(collection, &block)
642
- results = collection.map do |obj|
643
- result = yield(obj)
644
-
645
- if result.failure?
646
- return result
647
- end
648
-
649
- result
567
+ def same_type?(relation)
568
+ if assumptions.include?(relation) && assumptions.include?(relation.flip)
569
+ return true
650
570
  end
651
571
 
652
- results[0]
572
+ relation.sub_type == relation.super_type
653
573
  end
654
574
 
655
- def success_any?(collection, &block)
656
- results = collection.map do |obj|
657
- result = yield(obj)
575
+ def check_interface(relation)
576
+ relation.interface!
658
577
 
659
- if result.success?
660
- return result
661
- end
578
+ sub_interface, super_interface = relation
662
579
 
663
- result
580
+ method_pairs = super_interface.methods.each_with_object({}) do |(method_name, sup_method), hash|
581
+ if sub_method = sub_interface.methods[method_name]
582
+ hash[method_name] = Relation.new(sub_type: sub_method, super_type: sup_method)
583
+ else
584
+ return Failure(relation) { Result::Failure::MethodMissingError.new(name: method_name) }
585
+ end
664
586
  end
665
587
 
666
- results[0]
588
+ All(relation) do |result|
589
+ method_pairs.each do |method_name, method_relation|
590
+ result.add(relation) do
591
+ check_method(method_name, method_relation)
592
+ end
593
+ end
594
+ end
667
595
  end
668
596
 
669
- def extract_nominal_pairs(relation)
670
- sub_type = relation.sub_type
671
- super_type = relation.super_type
597
+ def check_method(name, relation)
598
+ relation.method!
672
599
 
673
- case
674
- when sub_type.is_a?(AST::Types::Name::Instance) && super_type.is_a?(AST::Types::Name::Instance)
675
- if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
676
- sub_type.args.zip(super_type.args)
677
- end
678
- when sub_type.is_a?(AST::Types::Name::Interface) && super_type.is_a?(AST::Types::Name::Interface)
679
- if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
680
- sub_type.args.zip(super_type.args)
681
- end
682
- when sub_type.is_a?(AST::Types::Name::Alias) && super_type.is_a?(AST::Types::Name::Alias)
683
- if sub_type.name == super_type.name && sub_type.args.size == super_type.args.size
684
- sub_type.args.zip(super_type.args)
685
- end
686
- when sub_type.is_a?(AST::Types::Name::Singleton) && super_type.is_a?(AST::Types::Name::Singleton)
687
- if sub_type.name == super_type.name
688
- []
600
+ sub_method, super_method = relation
601
+
602
+ All(relation) do |all|
603
+ super_method.method_types.each do |super_type|
604
+ all.add(Relation.new(sub_type: sub_method, super_type: super_type)) do |rel|
605
+ Any(rel) do |any|
606
+ sub_method.method_types.each do |sub_type|
607
+ any.add(Relation.new(sub_type: sub_type, super_type: super_type)) do |rel|
608
+ check_generic_method_type(name, rel)
609
+ end
610
+ end
611
+ end
612
+ end
689
613
  end
690
614
  end
691
615
  end
692
616
 
693
- def same_type?(relation, assumption:)
694
- if assumption.include?(relation) && assumption.include?(relation.flip)
695
- return true
617
+ def check_type_application(result, type_params, type_args)
618
+ raise unless type_params.size == type_args.size
619
+
620
+ rels = type_params.zip(type_args).filter_map do |(param, arg)|
621
+ if ub = param.upper_bound
622
+ Relation.new(sub_type: arg, super_type: ub.subst(sub))
623
+ end
696
624
  end
697
625
 
698
- relation.sub_type == relation.super_type
626
+ result.add(*rels) {|rel| check_type(rel) } and yield
699
627
  end
700
628
 
701
- def check_interface(sub_interface, super_interface, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
702
- trace.interface sub_interface, super_interface do
703
- method_triples = []
629
+ def check_generic_method_type(name, relation)
630
+ relation.method!
704
631
 
705
- super_interface.methods.each do |name, sup_method|
706
- sub_method = sub_interface.methods[name]
707
-
708
- if sub_method
709
- method_triples << [name, sub_method, sup_method]
710
- else
711
- return failure(error: Result::Failure::MethodMissingError.new(name: name),
712
- trace: trace)
713
- end
714
- end
632
+ sub_type, super_type = relation
715
633
 
716
- method_triples.each do |(method_name, sub_method, sup_method)|
717
- result = check_method(method_name,
718
- sub_method,
719
- sup_method,
720
- self_type: self_type,
721
- instance_type: instance_type,
722
- class_type: class_type,
723
- assumption: assumption,
724
- trace: trace,
725
- constraints: constraints)
726
- return result if result.failure?
727
- end
634
+ case
635
+ when sub_type.type_params.empty? && super_type.type_params.empty?
636
+ check_method_type(name, relation)
728
637
 
729
- success(constraints: constraints)
730
- end
731
- end
638
+ when !sub_type.type_params.empty? && super_type.type_params.empty?
639
+ # Check if super_type is an instance of sub_type.
640
+ Expand(relation) do
641
+ sub_args = sub_type.type_params.map {|param| AST::Types::Var.fresh(param.name) }
642
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params.map(&:name), sub_args))
732
643
 
733
- def check_method(name, sub_method, super_method, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
734
- trace.method name, sub_method, super_method do
735
- super_method.method_types.map do |super_type|
736
- sub_method.method_types.map do |sub_type|
737
- check_generic_method_type name,
738
- sub_type,
739
- super_type,
740
- self_type: self_type,
741
- instance_type: instance_type,
742
- class_type: class_type,
743
- assumption: assumption,
744
- trace: trace,
745
- constraints: constraints
746
- end.yield_self do |results|
747
- results.find(&:success?) || results[0]
748
- end
749
- end.yield_self do |results|
750
- if results.all?(&:success?)
751
- success constraints: constraints
752
- else
753
- results.select(&:failure?).last
644
+ sub_args.each do |s|
645
+ constraints.unknown!(s.name)
754
646
  end
755
- end
756
- end
757
- end
758
647
 
759
- def check_generic_method_type(name, sub_type, super_type, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
760
- trace.method_type name, sub_type, super_type do
761
- case
762
- when sub_type.type_params.empty? && super_type.type_params.empty?
763
- check_method_type name,
764
- sub_type,
765
- super_type,
766
- self_type: self_type,
767
- instance_type: instance_type,
768
- class_type: class_type,
769
- assumption: assumption,
770
- trace: trace,
771
- constraints: constraints
772
-
773
- when !sub_type.type_params.empty? && super_type.type_params.empty?
774
- # Check if super_type is an instance of sub_type.
775
- yield_self do
776
- sub_args = sub_type.type_params.map {|x| AST::Types::Var.fresh(x) }
777
- sub_type = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params, sub_args))
778
-
779
- constraints.add_var(*sub_args)
780
-
781
- match_method_type(name, sub_type, super_type, trace: trace).yield_self do |pairs|
782
- case pairs
783
- when Array
784
- subst = pairs.each.with_object(Interface::Substitution.empty) do |(sub, sup), subst|
785
- case
786
- when sub.is_a?(AST::Types::Var) && sub_args.include?(sub)
787
- if subst.key?(sub.name) && subst[sub.name] != sup
788
- return failure(error: Result::Failure::PolyMethodSubtyping.new(name: name),
789
- trace: trace)
790
- else
791
- subst.add!(sub.name, sup)
792
- end
793
- when sup.is_a?(AST::Types::Var) && sub_args.include?(sup)
794
- if subst.key?(sup.name) && subst[sup.name] != sub
795
- return failure(error: Result::Failure::PolyMethodSubtyping.new(name: name),
796
- trace: trace)
797
- else
798
- subst.add!(sup.name, sub)
799
- end
800
- end
648
+ relation = Relation.new(sub_type: sub_type_, super_type: super_type)
649
+ All(relation) do |result|
650
+ sub_args.zip(sub_type.type_params).each do |(arg, param)|
651
+ if ub = param.upper_bound
652
+ result.add(Relation.new(sub_type: arg, super_type: ub)) do |rel|
653
+ check_type(rel)
801
654
  end
802
-
803
- check_method_type(name,
804
- sub_type.subst(subst),
805
- super_type,
806
- self_type: self_type,
807
- instance_type: instance_type,
808
- class_type: class_type,
809
- assumption: assumption,
810
- trace: trace,
811
- constraints: constraints)
812
- else
813
- pairs
814
655
  end
815
656
  end
816
- end
817
657
 
818
- when sub_type.type_params.empty? && !super_type.type_params.empty?
819
- # Check if sub_type is an instance of super_type && no constraints on type variables (any).
820
- yield_self do
821
- sub_args = sub_type.type_params.map {|x| AST::Types::Var.fresh(x) }
822
- sub_type = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params, sub_args))
823
-
824
- constraints.add_var(*sub_args)
825
-
826
- match_method_type(name, sub_type, super_type, trace: trace).yield_self do |pairs|
827
- case pairs
828
- when Array
829
- result = check_method_type(name,
830
- sub_type,
831
- super_type,
832
- self_type: self_type,
833
- instance_type: instance_type,
834
- class_type: class_type,
835
- assumption: assumption,
836
- trace: trace,
837
- constraints: constraints)
838
-
839
- if result.success? && sub_args.map(&:name).none? {|var| constraints.has_constraint?(var) }
840
- result
841
- else
842
- failure(error: Result::Failure::PolyMethodSubtyping.new(name: name),
843
- trace: trace)
658
+ match_method_type(name, relation) do |pairs|
659
+ rels =
660
+ pairs.each.with_object([]) do |(sub, sup), rels|
661
+ rels << Relation.new(sub_type: sub, super_type: sup)
662
+ rels << Relation.new(sub_type: sup, super_type: sub)
844
663
  end
845
664
 
846
- else
847
- pairs
665
+ result.add(*rels) do |rel|
666
+ check_type(rel)
667
+ end
668
+
669
+ result.add(Relation.new(sub_type: sub_type_, super_type: super_type)) do |rel|
670
+ check_method_type(
671
+ name,
672
+ Relation.new(sub_type: sub_type_, super_type: super_type)
673
+ )
848
674
  end
849
675
  end
676
+
677
+ result.add(relation) do |rel|
678
+ check_constraints(
679
+ relation,
680
+ variables: sub_args.map(&:name),
681
+ variance: VariableVariance.from_method_type(sub_type_)
682
+ )
683
+ end
684
+ end
685
+ end
686
+
687
+ when sub_type.type_params.empty? && !super_type.type_params.empty?
688
+ # Check if sub_type is an instance of super_type && no constraints on type variables (any).
689
+ Expand(relation) do
690
+ match_method_type(name, relation) do
691
+ sub_args = sub_type.type_params.map {|param| AST::Types::Var.fresh(param.name) }
692
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params.map(&:name), sub_args))
693
+
694
+ sub_args.each do |arg|
695
+ constraints.unknown!(arg.name)
696
+ end
697
+
698
+ rel_ = Relation.new(sub_type: sub_type_, super_type: super_type)
699
+ result = check_method_type(name, rel_)
700
+
701
+ if result.success? && sub_args.map(&:name).none? {|var| constraints.has_constraint?(var) }
702
+ result
703
+ else
704
+ Failure(rel_, Result::Failure::PolyMethodSubtyping.new(name: name))
705
+ end
850
706
  end
707
+ end
851
708
 
852
- when super_type.type_params.size == sub_type.type_params.size
853
- # Check if they have the same shape
854
- yield_self do
855
- args = sub_type.type_params.map {|x| AST::Types::Var.fresh(x) }
856
-
857
- sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params, args))
858
- super_type_ = super_type.instantiate(Interface::Substitution.build(super_type.type_params, args))
859
-
860
- constraints.add_var(*args)
861
-
862
- check_method_type(name,
863
- sub_type_,
864
- super_type_,
865
- self_type: self_type,
866
- instance_type: instance_type,
867
- class_type: class_type,
868
- assumption: assumption,
869
- trace: trace,
870
- constraints: constraints)
709
+ when super_type.type_params.size == sub_type.type_params.size
710
+ # If they have the same arity, run the normal F-sub subtyping checking.
711
+ All(relation) do |result|
712
+ args = sub_type.type_params.map {|type_param| AST::Types::Var.fresh(type_param.name) }
713
+ args.each {|arg| constraints.unknown!(arg.name) }
714
+
715
+ upper_bounds = {}
716
+ relations = []
717
+
718
+ args.zip(sub_type.type_params, super_type.type_params).each do |arg, sub_param, sup_param|
719
+ sub_ub = sub_param.upper_bound
720
+ sup_ub = sup_param.upper_bound
721
+
722
+ case
723
+ when sub_ub && sup_ub
724
+ upper_bounds[arg.name] = sub_ub
725
+ relations << Relation.new(sub_type: sub_ub, super_type: sup_ub)
726
+ when sub_ub && !sup_ub
727
+ upper_bounds[arg.name] = sub_ub
728
+ when !sub_ub && sup_ub
729
+ result.add(
730
+ Failure(relation, Result::Failure::PolyMethodSubtyping.new(name: name))
731
+ )
732
+ when !sub_ub && !sup_ub
733
+ # no constraints
734
+ end
871
735
  end
872
736
 
873
- else
874
- # Or error
875
- failure(error: Result::Failure::PolyMethodSubtyping.new(name: name),
876
- trace: trace)
737
+ push_variable_bounds(upper_bounds) do
738
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params.map(&:name), args))
739
+ super_type_ = super_type.instantiate(Interface::Substitution.build(super_type.type_params.map(&:name), args))
740
+
741
+ result.add(*relations) {|rel| check_type(rel) }
742
+ result.add(Relation.new(sub_type: sub_type_, super_type: super_type_)) do |rel|
743
+ check_method_type(name, rel)
744
+ end
745
+ end
877
746
  end
747
+
748
+ else
749
+ Failure(relation, Result::Failure::PolyMethodSubtyping.new(name: name))
878
750
  end
879
751
  end
880
752
 
881
- def check_method_type(name, sub_type, super_type, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
882
- Steep.logger.tagged("#{name}: #{sub_type} <: #{super_type}") do
883
- check_method_params(name, sub_type.type.params, super_type.type.params, self_type: self_type, instance_type: instance_type, class_type: class_type, assumption: assumption, trace: trace, constraints: constraints).then do
884
- check_block_given(name, sub_type.block, super_type.block, trace: trace, constraints: constraints).then do
885
- check_block_params(name, sub_type.block, super_type.block, self_type: self_type, instance_type: instance_type, class_type: class_type, assumption: assumption, trace: trace, constraints: constraints).then do
886
- check_block_return(sub_type.block, super_type.block, self_type: self_type, instance_type: instance_type, class_type: class_type, assumption: assumption, trace: trace, constraints:constraints).then do
887
- relation = Relation.new(super_type: super_type.type.return_type,
888
- sub_type: sub_type.type.return_type)
889
- check(
890
- relation,
891
- self_type: self_type,
892
- instance_type: instance_type,
893
- class_type: class_type,
894
- assumption: assumption,
895
- trace: trace,
896
- constraints: constraints
897
- )
898
- end
753
+ def check_constraints(relation, variables:, variance:)
754
+ checker = Check.new(factory: factory)
755
+
756
+ constraints.solution(
757
+ checker,
758
+ variance: variance,
759
+ variables: variables,
760
+ self_type: self_type,
761
+ instance_type: instance_type,
762
+ class_type: class_type
763
+ )
764
+
765
+ Success(relation)
766
+ rescue Constraints::UnsatisfiableConstraint => error
767
+ Failure(relation, Result::Failure::UnsatisfiedConstraints.new(error))
768
+ end
769
+
770
+ def check_method_type(name, relation)
771
+ relation.method!
772
+
773
+ sub_type, super_type = relation
774
+
775
+ All(relation) do |result|
776
+ result.add(Relation.new(sub_type: sub_type.type, super_type: super_type.type)) do |rel|
777
+ check_function(name, rel)
778
+ end
779
+
780
+ result.add(Relation.new(sub_type: sub_type.block, super_type: super_type.block)) do |rel|
781
+ check_block_given(name, rel) do
782
+ Expand(Relation.new(sub_type: super_type.block.type, super_type: sub_type.block.type)) do |rel|
783
+ check_function(name, rel)
899
784
  end
900
785
  end
901
786
  end
902
787
  end
903
788
  end
904
789
 
905
- def check_block_given(name, sub_block, super_block, trace:, constraints:)
790
+ def check_block_given(name, relation, &block)
791
+ relation.block!
792
+
793
+ sub_block, super_block = relation
794
+
906
795
  case
907
796
  when !super_block && !sub_block
908
- success(constraints: constraints)
797
+ Success(relation)
909
798
  when super_block && sub_block && super_block.optional? == sub_block.optional?
910
- success(constraints: constraints)
799
+ Expand(relation, &block)
911
800
  when sub_block&.optional?
912
- success(constraints: constraints)
801
+ Success(relation)
913
802
  else
914
- failure(
915
- error: Result::Failure::BlockMismatchError.new(name: name),
916
- trace: trace
917
- )
803
+ Failure(relation, Result::Failure::BlockMismatchError.new(name: name))
918
804
  end
919
805
  end
920
806
 
921
- def check_method_params(name, sub_params, super_params, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
922
- match_params(name, sub_params, super_params, trace: trace).yield_self do |pairs|
923
- case pairs
924
- when Array
925
- pairs.each do |(sub_type, super_type)|
926
- relation = Relation.new(super_type: sub_type, sub_type: super_type)
927
-
928
- result = check(relation,
929
- self_type: self_type,
930
- instance_type: instance_type,
931
- class_type: class_type,
932
- assumption: assumption,
933
- trace: trace,
934
- constraints: constraints)
935
- return result if result.failure?
936
- end
807
+ def check_function(name, relation)
808
+ relation.function!
809
+
810
+ All(relation) do |result|
811
+ result.add(relation.map {|fun| fun.params }) do |rel|
812
+ check_method_params(name, rel)
813
+ end
814
+
815
+ result.add(relation.map {|fun| fun.return_type }) do |rel|
816
+ check_type(rel)
817
+ end
818
+ end
819
+ end
820
+
821
+ def check_method_params(name, relation)
822
+ relation.params!
823
+ pairs = match_params(name, relation)
824
+
825
+ case pairs
826
+ when Array
827
+ unless pairs.empty?
828
+ All(relation) do |result|
829
+ pairs.each do |(sub_type, super_type)|
830
+ result.add(Relation.new(sub_type: super_type, super_type: sub_type)) do |rel|
831
+ check_type(rel)
832
+ end
833
+ end
937
834
 
938
- success(constraints: constraints)
835
+ result
836
+ end
939
837
  else
940
- pairs
838
+ Success(relation)
941
839
  end
840
+ else
841
+ pairs
942
842
  end
943
843
  end
944
844
 
945
- def match_method_type(name, sub_type, super_type, trace:)
946
- [].tap do |pairs|
947
- match_params(name, sub_type.type.params, super_type.type.params, trace: trace).yield_self do |result|
948
- return result unless result.is_a?(Array)
949
- pairs.push(*result)
950
- pairs.push [sub_type.type.return_type, super_type.type.return_type]
845
+ # ```rbs
846
+ # (Symbol, Relation[MethodType]) -> (Array[[Symbol, Symbol]] | Result::t)
847
+ # [A] (Symbol, Relation[MethodType]) { (Array[[Symbol, Symbol]]) -> A } -> (A | Result::t)
848
+ # ````
849
+ def match_method_type(name, relation)
850
+ relation.method!
951
851
 
952
- case
953
- when !super_type.block && !sub_type.block
954
- # No block required and given
852
+ sub_type, super_type = relation
955
853
 
956
- when super_type.block && sub_type.block
957
- match_params(name, super_type.block.type.params, sub_type.block.type.params, trace: trace).yield_self do |block_result|
958
- return block_result unless block_result.is_a?(Array)
959
- pairs.push(*block_result)
960
- pairs.push [super_type.block.type.return_type, sub_type.block.type.return_type]
961
- end
854
+ pairs = []
962
855
 
963
- else
964
- return failure(error: Result::Failure::BlockMismatchError.new(name: name),
965
- trace: trace)
966
- end
856
+ match_params(name, relation.map {|m| m.type.params }).tap do |param_pairs|
857
+ return param_pairs unless param_pairs.is_a?(Array)
858
+
859
+ pairs.push(*param_pairs)
860
+ pairs.push [sub_type.type.return_type, super_type.type.return_type]
861
+ end
862
+
863
+ check_block_given(name, relation.map {|m| m.block }) do |rel|
864
+ match_params(name, rel.map {|m| m.type.params }).tap do |param_pairs|
865
+ return param_pairs unless param_pairs.is_a?(Array)
866
+
867
+ pairs.push(*param_pairs)
868
+ pairs.push [sub_type.type.return_type, super_type.type.return_type]
967
869
  end
968
870
  end
871
+
872
+ if block_given?
873
+ yield pairs
874
+ else
875
+ pairs
876
+ end
969
877
  end
970
878
 
971
- def match_params(name, sub_params, super_params, trace:)
879
+ def match_params(name, relation)
880
+ relation.params!
881
+
882
+ sub_params, super_params = relation
883
+
972
884
  pairs = []
973
885
 
974
886
  sub_flat = sub_params.flat_unnamed_params
975
887
  sup_flat = super_params.flat_unnamed_params
976
888
 
977
- failure = failure(error: Result::Failure::ParameterMismatchError.new(name: name),
978
- trace: trace)
889
+ failure = Failure(relation, Result::Failure::ParameterMismatchError.new(name: name))
979
890
 
980
891
  case
981
892
  when super_params.rest
@@ -1060,43 +971,27 @@ module Steep
1060
971
  pairs
1061
972
  end
1062
973
 
1063
- def check_block_params(name, sub_block, super_block, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
1064
- if sub_block && super_block
1065
- check_method_params(name,
1066
- super_block.type.params,
1067
- sub_block.type.params,
1068
- self_type: self_type,
1069
- instance_type: instance_type,
1070
- class_type: class_type,
1071
- assumption: assumption,
1072
- trace: trace,
1073
- constraints: constraints)
1074
- else
1075
- success(constraints: constraints)
1076
- end
974
+ def expand_alias(type, &block)
975
+ factory.expand_alias(type, &block)
1077
976
  end
1078
977
 
1079
- def check_block_return(sub_block, super_block, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
1080
- if sub_block && super_block
1081
- relation = Relation.new(sub_type: super_block.type.return_type,
1082
- super_type: sub_block.type.return_type)
1083
- check(
1084
- relation,
1085
- self_type: self_type,
1086
- instance_type: instance_type,
1087
- class_type: class_type,
1088
- assumption: assumption,
1089
- trace: trace,
1090
- constraints: constraints
1091
- )
978
+ # Returns the shortest type paths for one of the _unknown_ type variables.
979
+ # Returns nil if there is no path.
980
+ def hole_path(type, path = [])
981
+ case type
982
+ when AST::Types::Var
983
+ if constraints.unknown?(type.name)
984
+ [type]
985
+ else
986
+ nil
987
+ end
1092
988
  else
1093
- success(constraints: constraints)
989
+ paths = type.each_child.map do |ty|
990
+ hole_path(ty, path)&.unshift(ty)
991
+ end
992
+ paths.compact.min_by(&:size)
1094
993
  end
1095
994
  end
1096
-
1097
- def expand_alias(type, &block)
1098
- factory.expand_alias(type, &block)
1099
- end
1100
995
  end
1101
996
  end
1102
997
  end