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