steep 0.47.0 → 0.49.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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +14 -16
  5. data/lib/steep/ast/types/any.rb +2 -0
  6. data/lib/steep/ast/types/boolean.rb +2 -0
  7. data/lib/steep/ast/types/bot.rb +2 -0
  8. data/lib/steep/ast/types/class.rb +2 -0
  9. data/lib/steep/ast/types/factory.rb +162 -138
  10. data/lib/steep/ast/types/helper.rb +8 -0
  11. data/lib/steep/ast/types/instance.rb +2 -0
  12. data/lib/steep/ast/types/intersection.rb +4 -0
  13. data/lib/steep/ast/types/literal.rb +2 -0
  14. data/lib/steep/ast/types/logic.rb +2 -0
  15. data/lib/steep/ast/types/name.rb +6 -0
  16. data/lib/steep/ast/types/nil.rb +2 -0
  17. data/lib/steep/ast/types/proc.rb +9 -0
  18. data/lib/steep/ast/types/record.rb +4 -0
  19. data/lib/steep/ast/types/self.rb +2 -0
  20. data/lib/steep/ast/types/top.rb +2 -0
  21. data/lib/steep/ast/types/tuple.rb +4 -0
  22. data/lib/steep/ast/types/union.rb +4 -0
  23. data/lib/steep/ast/types/var.rb +16 -3
  24. data/lib/steep/ast/types/void.rb +2 -0
  25. data/lib/steep/diagnostic/ruby.rb +23 -11
  26. data/lib/steep/diagnostic/signature.rb +56 -0
  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 +2 -1
  35. data/lib/steep/signature/validator.rb +221 -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 +543 -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 +4 -4
  46. data/sample/lib/length.rb +35 -0
  47. data/sample/sig/length.rbs +34 -0
  48. data/smoke/diagnostics-rbs/nonregular-type-alias.rbs +3 -0
  49. data/smoke/diagnostics-rbs/recursive-type-alias.rbs +3 -0
  50. data/smoke/diagnostics-rbs/test_expectations.yml +57 -12
  51. data/smoke/tsort/a.rb +1 -1
  52. data/smoke/tsort/test_expectations.yml +1 -63
  53. data/steep.gemspec +1 -1
  54. metadata +13 -10
  55. data/lib/steep/drivers/trace_printer.rb +0 -29
  56. data/lib/steep/interface/method.rb +0 -78
  57. 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