steep 0.47.1 → 0.48.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.
@@ -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,282 @@ 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.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.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?)
521
- end
522
-
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)
475
+ result.add(rel) do
476
+ check_type(rel)
477
+ end
545
478
  end
479
+ end
546
480
 
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
- )
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
563
485
 
486
+ when relation.super_type.is_a?(AST::Types::Literal)
487
+ case
488
+ when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
489
+ Success(relation)
490
+ when relation.super_type.value == false && AST::Builtin::FalseClass.instance_type?(relation.sub_type)
491
+ Success(relation)
564
492
  else
565
- failure(error: Result::Failure::UnknownPairError.new(relation: relation),
566
- trace: trace)
493
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
567
494
  end
495
+
496
+ when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
497
+ Success(relation)
498
+
499
+ when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
500
+ Success(relation)
501
+
502
+ when relation.sub_type.is_a?(AST::Types::Literal)
503
+ Expand(relation) do
504
+ check_type(Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type))
505
+ end
506
+
507
+ else
508
+ Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
568
509
  end
569
510
  end
570
511
 
@@ -592,390 +533,357 @@ module Steep
592
533
  end
593
534
  end
594
535
 
595
- def check_type_arg(relation, self_type:, instance_type:, class_type:, assumption:, trace:, constraints:)
536
+ def check_type_arg(relation)
596
537
  sub_args = relation.sub_type.args
597
538
  sup_args = relation.super_type.args
598
539
 
599
540
  sup_def = definition_for_type(relation.super_type)
600
541
  sup_params = sup_def.type_params_decl
601
542
 
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
- )
543
+ All(relation) do |result|
544
+ sub_args.zip(sup_args, sup_params.each).each do |sub_arg, sup_arg, sup_param|
545
+ case sup_param.variance
546
+ when :covariant
547
+ result.add(Relation.new(sub_type: sub_arg, super_type: sup_arg)) do |rel|
548
+ check_type(rel)
549
+ end
550
+ when :contravariant
551
+ result.add(Relation.new(sub_type: sup_arg, super_type: sub_arg)) do |rel|
552
+ check_type(rel)
553
+ end
554
+ when :invariant
555
+ rel = Relation.new(sub_type: sub_arg, super_type: sup_arg)
556
+ result.add(rel, rel.flip) do |rel|
557
+ check_type(rel)
558
+ end
636
559
  end
637
560
  end
638
561
  end
639
562
  end
640
563
 
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
564
+ def same_type?(relation)
565
+ if assumptions.include?(relation) && assumptions.include?(relation.flip)
566
+ return true
650
567
  end
651
568
 
652
- results[0]
569
+ relation.sub_type == relation.super_type
653
570
  end
654
571
 
655
- def success_any?(collection, &block)
656
- results = collection.map do |obj|
657
- result = yield(obj)
572
+ def check_interface(relation)
573
+ relation.interface!
658
574
 
659
- if result.success?
660
- return result
661
- end
575
+ sub_interface, super_interface = relation
662
576
 
663
- result
577
+ method_pairs = super_interface.methods.each_with_object({}) do |(method_name, sup_method), hash|
578
+ if sub_method = sub_interface.methods[method_name]
579
+ hash[method_name] = Relation.new(sub_type: sub_method, super_type: sup_method)
580
+ else
581
+ return Failure(relation) { Result::Failure::MethodMissingError.new(name: method_name) }
582
+ end
664
583
  end
665
584
 
666
- results[0]
585
+ All(relation) do |result|
586
+ method_pairs.each do |method_name, method_relation|
587
+ result.add(relation) do
588
+ check_method(method_name, method_relation)
589
+ end
590
+ end
591
+ end
667
592
  end
668
593
 
669
- def extract_nominal_pairs(relation)
670
- sub_type = relation.sub_type
671
- super_type = relation.super_type
594
+ def check_method(name, relation)
595
+ relation.method!
672
596
 
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
- []
597
+ sub_method, super_method = relation
598
+
599
+ All(relation) do |all|
600
+ super_method.method_types.each do |super_type|
601
+ all.add(Relation.new(sub_type: sub_method, super_type: super_type)) do |rel|
602
+ Any(rel) do |any|
603
+ sub_method.method_types.each do |sub_type|
604
+ any.add(Relation.new(sub_type: sub_type, super_type: super_type)) do |rel|
605
+ check_generic_method_type(name, rel)
606
+ end
607
+ end
608
+ end
609
+ end
689
610
  end
690
611
  end
691
612
  end
692
613
 
693
- def same_type?(relation, assumption:)
694
- if assumption.include?(relation) && assumption.include?(relation.flip)
695
- return true
614
+ def check_type_application(result, type_params, type_args)
615
+ raise unless type_params.size == type_args.size
616
+
617
+ rels = type_params.zip(type_args).filter_map do |(param, arg)|
618
+ if ub = param.upper_bound
619
+ Relation.new(sub_type: arg, super_type: ub.subst(sub))
620
+ end
696
621
  end
697
622
 
698
- relation.sub_type == relation.super_type
623
+ result.add(*rels) {|rel| check_type(rel) } and yield
699
624
  end
700
625
 
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 = []
704
-
705
- super_interface.methods.each do |name, sup_method|
706
- sub_method = sub_interface.methods[name]
626
+ def check_generic_method_type(name, relation)
627
+ relation.method!
707
628
 
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
629
+ sub_type, super_type = relation
715
630
 
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
631
+ case
632
+ when sub_type.type_params.empty? && super_type.type_params.empty?
633
+ check_method_type(name, relation)
728
634
 
729
- success(constraints: constraints)
730
- end
731
- end
635
+ when !sub_type.type_params.empty? && super_type.type_params.empty?
636
+ # Check if super_type is an instance of sub_type.
637
+ Expand(relation) do
638
+ sub_args = sub_type.type_params.map {|param| AST::Types::Var.fresh(param.name) }
639
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params.map(&:name), sub_args))
732
640
 
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
641
+ sub_args.each do |s|
642
+ constraints.unknown!(s.name)
754
643
  end
755
- end
756
- end
757
- end
758
644
 
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
645
+ relation = Relation.new(sub_type: sub_type_, super_type: super_type)
646
+ All(relation) do |result|
647
+ sub_args.zip(sub_type.type_params).each do |(arg, param)|
648
+ if ub = param.upper_bound
649
+ result.add(Relation.new(sub_type: arg, super_type: ub)) do |rel|
650
+ check_type(rel)
801
651
  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
652
  end
815
653
  end
816
- end
817
654
 
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)
655
+ match_method_type(name, relation) do |pairs|
656
+ rels =
657
+ pairs.each.with_object([]) do |(sub, sup), rels|
658
+ rels << Relation.new(sub_type: sub, super_type: sup)
659
+ rels << Relation.new(sub_type: sup, super_type: sub)
844
660
  end
845
661
 
846
- else
847
- pairs
662
+ result.add(*rels) do |rel|
663
+ check_type(rel)
664
+ end
665
+
666
+ result.add(Relation.new(sub_type: sub_type_, super_type: super_type)) do |rel|
667
+ check_method_type(
668
+ name,
669
+ Relation.new(sub_type: sub_type_, super_type: super_type)
670
+ )
848
671
  end
849
672
  end
673
+
674
+ result.add(relation) do |rel|
675
+ check_constraints(
676
+ relation,
677
+ variables: sub_args.map(&:name),
678
+ variance: VariableVariance.from_method_type(sub_type_)
679
+ )
680
+ end
681
+ end
682
+ end
683
+
684
+ when sub_type.type_params.empty? && !super_type.type_params.empty?
685
+ # Check if sub_type is an instance of super_type && no constraints on type variables (any).
686
+ Expand(relation) do
687
+ match_method_type(name, relation) do
688
+ sub_args = sub_type.type_params.map {|param| AST::Types::Var.fresh(param.name) }
689
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params.map(&:name), sub_args))
690
+
691
+ sub_args.each do |arg|
692
+ constraints.unknown!(arg.name)
693
+ end
694
+
695
+ rel_ = Relation.new(sub_type: sub_type_, super_type: super_type)
696
+ result = check_method_type(name, rel_)
697
+
698
+ if result.success? && sub_args.map(&:name).none? {|var| constraints.has_constraint?(var) }
699
+ result
700
+ else
701
+ Failure(rel_, Result::Failure::PolyMethodSubtyping.new(name: name))
702
+ end
850
703
  end
704
+ end
851
705
 
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)
706
+ when super_type.type_params.size == sub_type.type_params.size
707
+ # If they have the same arity, run the normal F-sub subtyping checking.
708
+ All(relation) do |result|
709
+ args = sub_type.type_params.map {|type_param| AST::Types::Var.fresh(type_param.name) }
710
+ args.each {|arg| constraints.unknown!(arg.name) }
711
+
712
+ upper_bounds = {}
713
+ relations = []
714
+
715
+ args.zip(sub_type.type_params, super_type.type_params).each do |arg, sub_param, sup_param|
716
+ sub_ub = sub_param.upper_bound
717
+ sup_ub = sup_param.upper_bound
718
+
719
+ case
720
+ when sub_ub && sup_ub
721
+ upper_bounds[arg.name] = sub_ub
722
+ relations << Relation.new(sub_type: sub_ub, super_type: sup_ub)
723
+ when sub_ub && !sup_ub
724
+ upper_bounds[arg.name] = sub_ub
725
+ when !sub_ub && sup_ub
726
+ result.add(
727
+ Failure(relation, Result::Failure::PolyMethodSubtyping.new(name: name))
728
+ )
729
+ when !sub_ub && !sup_ub
730
+ # no constraints
731
+ end
871
732
  end
872
733
 
873
- else
874
- # Or error
875
- failure(error: Result::Failure::PolyMethodSubtyping.new(name: name),
876
- trace: trace)
734
+ push_variable_bounds(upper_bounds) do
735
+ sub_type_ = sub_type.instantiate(Interface::Substitution.build(sub_type.type_params.map(&:name), args))
736
+ super_type_ = super_type.instantiate(Interface::Substitution.build(super_type.type_params.map(&:name), args))
737
+
738
+ result.add(*relations) {|rel| check_type(rel) }
739
+ result.add(Relation.new(sub_type: sub_type_, super_type: super_type_)) do |rel|
740
+ check_method_type(name, rel)
741
+ end
742
+ end
877
743
  end
744
+
745
+ else
746
+ Failure(relation, Result::Failure::PolyMethodSubtyping.new(name: name))
878
747
  end
879
748
  end
880
749
 
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
750
+ def check_constraints(relation, variables:, variance:)
751
+ checker = Check.new(factory: factory)
752
+
753
+ constraints.solution(
754
+ checker,
755
+ variance: variance,
756
+ variables: variables,
757
+ self_type: self_type,
758
+ instance_type: instance_type,
759
+ class_type: class_type
760
+ )
761
+
762
+ Success(relation)
763
+ rescue Constraints::UnsatisfiableConstraint => error
764
+ Failure(relation, Result::Failure::UnsatisfiedConstraints.new(error))
765
+ end
766
+
767
+ def check_method_type(name, relation)
768
+ relation.method!
769
+
770
+ sub_type, super_type = relation
771
+
772
+ All(relation) do |result|
773
+ result.add(Relation.new(sub_type: sub_type.type, super_type: super_type.type)) do |rel|
774
+ check_function(name, rel)
775
+ end
776
+
777
+ result.add(Relation.new(sub_type: sub_type.block, super_type: super_type.block)) do |rel|
778
+ check_block_given(name, rel) do
779
+ Expand(Relation.new(sub_type: super_type.block.type, super_type: sub_type.block.type)) do |rel|
780
+ check_function(name, rel)
899
781
  end
900
782
  end
901
783
  end
902
784
  end
903
785
  end
904
786
 
905
- def check_block_given(name, sub_block, super_block, trace:, constraints:)
787
+ def check_block_given(name, relation, &block)
788
+ relation.block!
789
+
790
+ sub_block, super_block = relation
791
+
906
792
  case
907
793
  when !super_block && !sub_block
908
- success(constraints: constraints)
794
+ Success(relation)
909
795
  when super_block && sub_block && super_block.optional? == sub_block.optional?
910
- success(constraints: constraints)
796
+ Expand(relation, &block)
911
797
  when sub_block&.optional?
912
- success(constraints: constraints)
798
+ Success(relation)
913
799
  else
914
- failure(
915
- error: Result::Failure::BlockMismatchError.new(name: name),
916
- trace: trace
917
- )
800
+ Failure(relation, Result::Failure::BlockMismatchError.new(name: name))
918
801
  end
919
802
  end
920
803
 
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
804
+ def check_function(name, relation)
805
+ relation.function!
806
+
807
+ All(relation) do |result|
808
+ result.add(relation.map {|fun| fun.params }) do |rel|
809
+ check_method_params(name, rel)
810
+ end
811
+
812
+ result.add(relation.map {|fun| fun.return_type }) do |rel|
813
+ check_type(rel)
814
+ end
815
+ end
816
+ end
817
+
818
+ def check_method_params(name, relation)
819
+ relation.params!
820
+ pairs = match_params(name, relation)
821
+
822
+ case pairs
823
+ when Array
824
+ unless pairs.empty?
825
+ All(relation) do |result|
826
+ pairs.each do |(sub_type, super_type)|
827
+ result.add(Relation.new(sub_type: super_type, super_type: sub_type)) do |rel|
828
+ check_type(rel)
829
+ end
830
+ end
937
831
 
938
- success(constraints: constraints)
832
+ result
833
+ end
939
834
  else
940
- pairs
835
+ Success(relation)
941
836
  end
837
+ else
838
+ pairs
942
839
  end
943
840
  end
944
841
 
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]
842
+ # ```rbs
843
+ # (Symbol, Relation[MethodType]) -> (Array[[Symbol, Symbol]] | Result::t)
844
+ # [A] (Symbol, Relation[MethodType]) { (Array[[Symbol, Symbol]]) -> A } -> (A | Result::t)
845
+ # ````
846
+ def match_method_type(name, relation)
847
+ relation.method!
951
848
 
952
- case
953
- when !super_type.block && !sub_type.block
954
- # No block required and given
849
+ sub_type, super_type = relation
955
850
 
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
851
+ pairs = []
962
852
 
963
- else
964
- return failure(error: Result::Failure::BlockMismatchError.new(name: name),
965
- trace: trace)
966
- end
853
+ match_params(name, relation.map {|m| m.type.params }).tap do |param_pairs|
854
+ return param_pairs unless param_pairs.is_a?(Array)
855
+
856
+ pairs.push(*param_pairs)
857
+ pairs.push [sub_type.type.return_type, super_type.type.return_type]
858
+ end
859
+
860
+ check_block_given(name, relation.map {|m| m.block }) do |rel|
861
+ match_params(name, rel.map {|m| m.type.params }).tap do |param_pairs|
862
+ return param_pairs unless param_pairs.is_a?(Array)
863
+
864
+ pairs.push(*param_pairs)
865
+ pairs.push [sub_type.type.return_type, super_type.type.return_type]
967
866
  end
968
867
  end
868
+
869
+ if block_given?
870
+ yield pairs
871
+ else
872
+ pairs
873
+ end
969
874
  end
970
875
 
971
- def match_params(name, sub_params, super_params, trace:)
876
+ def match_params(name, relation)
877
+ relation.params!
878
+
879
+ sub_params, super_params = relation
880
+
972
881
  pairs = []
973
882
 
974
883
  sub_flat = sub_params.flat_unnamed_params
975
884
  sup_flat = super_params.flat_unnamed_params
976
885
 
977
- failure = failure(error: Result::Failure::ParameterMismatchError.new(name: name),
978
- trace: trace)
886
+ failure = Failure(relation, Result::Failure::ParameterMismatchError.new(name: name))
979
887
 
980
888
  case
981
889
  when super_params.rest
@@ -1060,40 +968,6 @@ module Steep
1060
968
  pairs
1061
969
  end
1062
970
 
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
1077
- end
1078
-
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
- )
1092
- else
1093
- success(constraints: constraints)
1094
- end
1095
- end
1096
-
1097
971
  def expand_alias(type, &block)
1098
972
  factory.expand_alias(type, &block)
1099
973
  end