steep 0.47.1 → 0.48.0

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