steep 1.7.0.dev.1 → 1.7.0.dev.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +13 -15
  3. data/Rakefile +5 -0
  4. data/gemfile_steep/Gemfile +1 -1
  5. data/gemfile_steep/Gemfile.lock +11 -13
  6. data/lib/steep/ast/types/helper.rb +4 -0
  7. data/lib/steep/ast/types/intersection.rb +7 -0
  8. data/lib/steep/ast/types/record.rb +7 -0
  9. data/lib/steep/ast/types/tuple.rb +7 -0
  10. data/lib/steep/ast/types/union.rb +7 -0
  11. data/lib/steep/drivers/stats.rb +2 -2
  12. data/lib/steep/drivers/validate.rb +4 -2
  13. data/lib/steep/expectations.rb +2 -2
  14. data/lib/steep/interface/builder.rb +336 -360
  15. data/lib/steep/interface/function.rb +69 -6
  16. data/lib/steep/interface/method_type.rb +3 -3
  17. data/lib/steep/interface/shape.rb +69 -18
  18. data/lib/steep/interface/substitution.rb +4 -0
  19. data/lib/steep/node_helper.rb +18 -1
  20. data/lib/steep/services/completion_provider.rb +19 -17
  21. data/lib/steep/services/signature_help_provider.rb +19 -20
  22. data/lib/steep/subtyping/check.rb +10 -16
  23. data/lib/steep/subtyping/result.rb +6 -0
  24. data/lib/steep/test.rb +9 -0
  25. data/lib/steep/type_construction.rb +13 -13
  26. data/lib/steep/type_inference/block_params.rb +11 -3
  27. data/lib/steep/type_inference/context.rb +1 -1
  28. data/lib/steep/type_inference/logic_type_interpreter.rb +1 -1
  29. data/lib/steep/version.rb +1 -1
  30. data/lib/steep.rb +11 -7
  31. data/sig/steep/ast/types/helper.rbs +2 -0
  32. data/sig/steep/ast/types/intersection.rbs +2 -0
  33. data/sig/steep/ast/types/name.rbs +4 -0
  34. data/sig/steep/ast/types/record.rbs +2 -0
  35. data/sig/steep/ast/types/tuple.rbs +2 -0
  36. data/sig/steep/ast/types/union.rbs +2 -0
  37. data/sig/steep/expectations.rbs +1 -1
  38. data/sig/steep/interface/block.rbs +2 -2
  39. data/sig/steep/interface/builder.rbs +94 -108
  40. data/sig/steep/interface/function.rbs +34 -29
  41. data/sig/steep/interface/shape.rbs +23 -4
  42. data/sig/steep/interface/substitution.rbs +2 -0
  43. data/sig/steep/node_helper.rbs +11 -0
  44. data/sig/steep/services/signature_help_provider.rbs +2 -0
  45. data/sig/steep/subtyping/check.rbs +2 -0
  46. data/sig/steep/subtyping/constraints.rbs +2 -2
  47. data/sig/steep/subtyping/result.rbs +5 -1
  48. data/sig/steep/type_construction.rbs +1 -1
  49. data/sig/steep/type_inference/block_params.rbs +2 -2
  50. data/sig/steep/type_inference/context.rbs +2 -0
  51. data/sig/steep.rbs +1 -1
  52. metadata +3 -3
  53. data/sig/steep/type_inference/branch.rbs +0 -15
@@ -163,71 +163,93 @@ module Steep
163
163
 
164
164
  case
165
165
  when x.is_a?(Required) && y.is_a?(Required)
166
+ xs or raise
167
+ ys or raise
166
168
  required(
167
169
  union(x.type, y.type),
168
170
  merge_for_overload(xs.tail, ys.tail)
169
171
  )
170
172
  when x.is_a?(Required) && y.is_a?(Optional)
173
+ xs or raise
174
+ ys or raise
171
175
  optional(
172
176
  union(x.type, y.type, null: true),
173
177
  merge_for_overload(xs.tail, ys.tail)
174
178
  )
175
179
  when x.is_a?(Required) && y.is_a?(Rest)
180
+ xs or raise
181
+ ys or raise
176
182
  optional(
177
183
  union(x.type, y.type, null: true),
178
184
  merge_for_overload(xs.tail, ys)
179
185
  )
180
186
  when x.is_a?(Required) && !y
187
+ xs or raise
181
188
  optional(
182
189
  union(x.type, null: true),
183
190
  merge_for_overload(xs.tail, nil)
184
191
  )
185
192
  when x.is_a?(Optional) && y.is_a?(Required)
193
+ xs or raise
194
+ ys or raise
186
195
  optional(
187
196
  union(x.type, y.type, null: true),
188
197
  merge_for_overload(xs.tail, ys.tail)
189
198
  )
190
199
  when x.is_a?(Optional) && y.is_a?(Optional)
200
+ xs or raise
201
+ ys or raise
191
202
  optional(
192
203
  union(x.type, y.type),
193
204
  merge_for_overload(xs.tail, ys.tail)
194
205
  )
195
206
  when x.is_a?(Optional) && y.is_a?(Rest)
207
+ xs or raise
208
+ ys or raise
196
209
  optional(
197
210
  union(x.type, y.type),
198
211
  merge_for_overload(xs.tail, ys)
199
212
  )
200
213
  when x.is_a?(Optional) && !y
214
+ xs or raise
201
215
  optional(
202
216
  x.type,
203
217
  merge_for_overload(xs.tail, nil)
204
218
  ) # == xs
205
219
  when x.is_a?(Rest) && y.is_a?(Required)
220
+ xs or raise
221
+ ys or raise
206
222
  optional(
207
223
  union(x.type, y.type, null: true),
208
224
  merge_for_overload(xs, ys.tail)
209
225
  )
210
226
  when x.is_a?(Rest) && y.is_a?(Optional)
227
+ xs or raise
228
+ ys or raise
211
229
  optional(
212
230
  union(x.type, y.type),
213
231
  merge_for_overload(xs, ys.tail)
214
232
  )
215
233
  when x.is_a?(Rest) && y.is_a?(Rest)
234
+ xs or raise
235
+ ys or raise
216
236
  rest(union(x.type, y.type))
217
237
  when x.is_a?(Rest) && !y
218
- xs
238
+ xs or raise
219
239
  when !x && y.is_a?(Required)
240
+ ys or raise
220
241
  optional(
221
242
  union(y.type, null: true),
222
243
  merge_for_overload(nil, ys.tail)
223
244
  )
224
245
  when !x && y.is_a?(Optional)
246
+ ys or raise
225
247
  optional(
226
248
  y.type,
227
249
  merge_for_overload(nil, ys.tail)
228
250
  ) # == ys
229
251
  when !x && y.is_a?(Rest)
230
- ys
252
+ ys or raise
231
253
  when !x && !y
232
254
  nil
233
255
  end
@@ -240,26 +262,34 @@ module Steep
240
262
 
241
263
  case
242
264
  when x.is_a?(Required) && y.is_a?(Required)
265
+ xs or raise
266
+ ys or raise
243
267
  required(
244
268
  union(x.type, y.type),
245
269
  merge_for_union(xs.tail, ys.tail)
246
270
  )
247
271
  when x.is_a?(Required) && !y
272
+ xs or raise
248
273
  optional(
249
274
  x.type,
250
275
  merge_for_union(xs.tail, nil)
251
276
  )
252
277
  when x.is_a?(Required) && y.is_a?(Optional)
278
+ xs or raise
279
+ ys or raise
253
280
  optional(
254
281
  union(x.type, y.type),
255
282
  merge_for_union(xs.tail, ys.tail)
256
283
  )
257
284
  when x.is_a?(Required) && y.is_a?(Rest)
285
+ xs or raise
286
+ ys or raise
258
287
  optional(
259
288
  union(x.type, y.type),
260
289
  merge_for_union(xs.tail, ys)
261
290
  )
262
291
  when !x && y.is_a?(Required)
292
+ ys or raise
263
293
  optional(
264
294
  y.type,
265
295
  merge_for_union(nil, ys.tail)
@@ -267,39 +297,53 @@ module Steep
267
297
  when !x && !y
268
298
  nil
269
299
  when !x && y.is_a?(Optional)
300
+ ys or raise
270
301
  PositionalParams.new(head: y, tail: merge_for_union(nil, ys.tail))
271
302
  when !x && y.is_a?(Rest)
272
- ys
303
+ ys or raise
273
304
  when x.is_a?(Optional) && y.is_a?(Required)
305
+ xs or raise
306
+ ys or raise
274
307
  optional(
275
308
  union(x.type, y.type),
276
309
  merge_for_union(xs.tail, ys.tail)
277
310
  )
278
311
  when x.is_a?(Optional) && !y
312
+ xs or raise
279
313
  PositionalParams.new(head: x, tail: merge_for_union(xs.tail, nil)) # == xs
280
314
  when x.is_a?(Optional) && y.is_a?(Optional)
315
+ xs or raise
316
+ ys or raise
281
317
  optional(
282
318
  union(x.type, y.type),
283
319
  merge_for_union(xs.tail, ys.tail)
284
320
  )
285
321
  when x.is_a?(Optional) && y.is_a?(Rest)
322
+ xs or raise
323
+ ys or raise
286
324
  optional(
287
325
  union(x.type, y.type),
288
326
  merge_for_union(xs.tail, ys.tail)
289
327
  )
290
328
  when x.is_a?(Rest) && y.is_a?(Required)
329
+ xs or raise
330
+ ys or raise
291
331
  optional(
292
332
  union(x.type, y.type),
293
333
  merge_for_union(xs, ys.tail)
294
334
  )
295
335
  when x.is_a?(Rest) && !y
296
- xs
336
+ xs or raise
297
337
  when x.is_a?(Rest) && y.is_a?(Optional)
338
+ xs or raise
339
+ ys or raise
298
340
  optional(
299
341
  union(x.type, y.type),
300
342
  merge_for_union(xs, ys.tail)
301
343
  )
302
344
  when x.is_a?(Rest) && y.is_a?(Rest)
345
+ xs or raise
346
+ ys or raise
303
347
  rest(
304
348
  union(x.type, y.type)
305
349
  )
@@ -315,6 +359,8 @@ module Steep
315
359
 
316
360
  case
317
361
  when x.is_a?(Required) && y.is_a?(Required)
362
+ xs or raise
363
+ ys or raise
318
364
  required(
319
365
  intersection(x.type, y.type),
320
366
  merge_for_intersection(xs.tail, ys.tail)
@@ -322,11 +368,15 @@ module Steep
322
368
  when x.is_a?(Required) && !y
323
369
  raise
324
370
  when x.is_a?(Required) && y.is_a?(Optional)
371
+ xs or raise
372
+ ys or raise
325
373
  required(
326
374
  intersection(x.type, y.type),
327
375
  merge_for_intersection(xs.tail, ys.tail)
328
376
  )
329
377
  when x.is_a?(Required) && y.is_a?(Rest)
378
+ xs or raise
379
+ ys or raise
330
380
  required(
331
381
  intersection(x.type, y.type),
332
382
  merge_for_intersection(xs.tail, ys)
@@ -340,6 +390,8 @@ module Steep
340
390
  when !x && y.is_a?(Rest)
341
391
  nil
342
392
  when x.is_a?(Optional) && y.is_a?(Required)
393
+ xs or raise
394
+ ys or raise
343
395
  required(
344
396
  intersection(x.type, y.type),
345
397
  merge_for_intersection(xs.tail, ys.tail)
@@ -347,16 +399,22 @@ module Steep
347
399
  when x.is_a?(Optional) && !y
348
400
  nil
349
401
  when x.is_a?(Optional) && y.is_a?(Optional)
402
+ xs or raise
403
+ ys or raise
350
404
  optional(
351
405
  intersection(x.type, y.type),
352
406
  merge_for_intersection(xs.tail, ys.tail)
353
407
  )
354
408
  when x.is_a?(Optional) && y.is_a?(Rest)
409
+ xs or raise
410
+ ys or raise
355
411
  optional(
356
412
  intersection(x.type, y.type),
357
413
  merge_for_intersection(xs.tail, ys)
358
414
  )
359
415
  when x.is_a?(Rest) && y.is_a?(Required)
416
+ xs or raise
417
+ ys or raise
360
418
  required(
361
419
  intersection(x.type, y.type),
362
420
  merge_for_intersection(xs, ys.tail)
@@ -364,6 +422,8 @@ module Steep
364
422
  when x.is_a?(Rest) && !y
365
423
  nil
366
424
  when x.is_a?(Rest) && y.is_a?(Optional)
425
+ xs or raise
426
+ ys or raise
367
427
  optional(
368
428
  intersection(x.type, y.type),
369
429
  merge_for_intersection(xs, ys.tail)
@@ -705,6 +765,8 @@ module Steep
705
765
  return param.type
706
766
  end
707
767
  end
768
+
769
+ nil
708
770
  end
709
771
 
710
772
  attr_reader :positional_params
@@ -836,7 +898,7 @@ module Steep
836
898
  end
837
899
 
838
900
  def closed?
839
- each_type.all?(&:closed?)
901
+ each_type.all? { _1.free_variables.empty? }
840
902
  end
841
903
 
842
904
  def subst(s)
@@ -945,6 +1007,7 @@ module Steep
945
1007
 
946
1008
  def free_variables
947
1009
  @fvs ||= Set[].tap do |fvs|
1010
+ # @type var fvs: Set[AST::Types::variable]
948
1011
  fvs.merge(params.free_variables)
949
1012
  fvs.merge(return_type.free_variables)
950
1013
  end
@@ -999,7 +1062,7 @@ module Steep
999
1062
  end
1000
1063
 
1001
1064
  def closed?
1002
- params.closed? && return_type.closed?
1065
+ params.closed? && return_type.free_variables.empty?
1003
1066
  end
1004
1067
  end
1005
1068
  end
@@ -192,10 +192,10 @@ module Steep
192
192
  type2_ = type2.instantiate(s2)
193
193
  if mt = generate[type1_, type2_]
194
194
  check.push_variable_bounds(params1 + params2) do
195
- variables = type1.type_params.map(&:name) + type2.type_params.map(&:name)
196
- constraints = Subtyping::Constraints.new(unknowns: variables)
195
+ variables = type1.type_params.map(&:name) + type2.type_params.map(&:name)
196
+ constraints = Subtyping::Constraints.new(unknowns: variables)
197
197
 
198
- check.with_context(self_type: AST::Builtin.any_type, instance_type: AST::Builtin.any_type, class_type: AST::Builtin.any_type, constraints: constraints) do
198
+ check.with_context(self_type: AST::Builtin.any_type, instance_type: AST::Builtin.any_type, class_type: AST::Builtin.any_type, constraints: constraints) do
199
199
  result1 = check.check_method_type(:__method_on_type1, relation[type1.with(type_params: []), mt])
200
200
  result2 = check.check_method_type(:__method_on_type2, relation[type2.with(type_params: []), mt])
201
201
 
@@ -2,14 +2,43 @@ module Steep
2
2
  module Interface
3
3
  class Shape
4
4
  class Entry
5
- attr_reader :method_types
6
-
7
- def initialize(method_types:)
5
+ def initialize(method_types: nil, private_method:, &block)
8
6
  @method_types = method_types
7
+ @generator = block
8
+ @private_method = private_method
9
+ end
10
+
11
+ def force
12
+ unless @method_types
13
+ @method_types = @generator&.call
14
+ @generator = nil
15
+ end
16
+ end
17
+
18
+ def method_types
19
+ force
20
+ @method_types or raise
21
+ end
22
+
23
+ def has_method_type?
24
+ force
25
+ @method_types ? true : false
9
26
  end
10
27
 
11
28
  def to_s
12
- "{ #{method_types.join(" || ")} }"
29
+ if @generator
30
+ "<< Lazy entry >>"
31
+ else
32
+ "{ #{method_types.join(" || ")} }"
33
+ end
34
+ end
35
+
36
+ def private_method?
37
+ @private_method
38
+ end
39
+
40
+ def public_method?
41
+ !private_method?
13
42
  end
14
43
  end
15
44
 
@@ -25,7 +54,11 @@ module Steep
25
54
  end
26
55
 
27
56
  def key?(name)
28
- methods.key?(name)
57
+ if entry = methods.fetch(name, nil)
58
+ entry.has_method_type?
59
+ else
60
+ false
61
+ end
29
62
  end
30
63
 
31
64
  def []=(name, entry)
@@ -37,10 +70,12 @@ module Steep
37
70
  return nil unless key?(name)
38
71
 
39
72
  resolved_methods[name] ||= begin
73
+ entry = methods[name]
40
74
  Entry.new(
41
- method_types: methods[name].method_types.map do |method_type|
75
+ method_types: entry.method_types.map do |method_type|
42
76
  method_type.subst(subst)
43
- end
77
+ end,
78
+ private_method: entry.private_method?
44
79
  )
45
80
  end
46
81
  end
@@ -48,7 +83,7 @@ module Steep
48
83
  def each(&block)
49
84
  if block
50
85
  methods.each_key do |name|
51
- entry = self[name] or raise
86
+ entry = self[name] or next
52
87
  yield [name, entry]
53
88
  end
54
89
  else
@@ -58,7 +93,9 @@ module Steep
58
93
 
59
94
  def each_name(&block)
60
95
  if block
61
- methods.each_key(&block)
96
+ each do |name, _|
97
+ yield name
98
+ end
62
99
  else
63
100
  enum_for :each_name
64
101
  end
@@ -76,19 +113,21 @@ module Steep
76
113
  Methods.new(substs: [*substs, subst], methods: methods)
77
114
  end
78
115
 
79
- def merge!(other)
116
+ def merge!(other, &block)
80
117
  other.each do |name, entry|
81
- methods[name] = entry
118
+ if block && (old_entry = methods[name])
119
+ methods[name] = yield(name, old_entry, entry)
120
+ else
121
+ methods[name] = entry
122
+ end
82
123
  end
83
124
  end
84
125
 
85
- def +(other)
86
- methods = Methods.new(substs: [], methods: {})
87
-
88
- methods.merge!(self)
89
- methods.merge!(other)
90
-
91
- methods
126
+ def public_methods
127
+ Methods.new(
128
+ substs: substs,
129
+ methods: methods.reject {|_, entry| entry.private_method? }
130
+ )
92
131
  end
93
132
  end
94
133
 
@@ -127,6 +166,18 @@ module Steep
127
166
  def public?
128
167
  !private?
129
168
  end
169
+
170
+ def public_shape
171
+ if public?
172
+ self
173
+ else
174
+ @public_shape ||= Shape.new(
175
+ type: type,
176
+ private: false,
177
+ methods: methods.public_methods
178
+ )
179
+ end
180
+ end
130
181
  end
131
182
  end
132
183
  end
@@ -138,6 +138,10 @@ module Steep
138
138
  self
139
139
  end
140
140
 
141
+ def update(self_type: self_type(), instance_type: instance_type(), module_type: module_type())
142
+ Substitution.new(dictionary: dictionary.dup, instance_type: instance_type, self_type: self_type, module_type: module_type)
143
+ end
144
+
141
145
  def merge(s)
142
146
  Substitution.new(dictionary: dictionary.dup,
143
147
  instance_type: instance_type,
@@ -207,7 +207,7 @@ module Steep
207
207
  end
208
208
 
209
209
  def deconstruct_send_node!(node)
210
- deconstruct_send_node(node) or raise
210
+ deconstruct_send_node(node) or raise(node.inspect)
211
211
  end
212
212
 
213
213
  def test_send_node(node)
@@ -218,6 +218,23 @@ module Steep
218
218
  end
219
219
  end
220
220
 
221
+ def private_send?(node)
222
+ case node.type
223
+ when :block, :numblock
224
+ private_send?(node.children[0])
225
+ when :send, :csend
226
+ receiver, = deconstruct_send_node!(node)
227
+
228
+ if receiver && receiver.type != :self
229
+ return false
230
+ end
231
+
232
+ true
233
+ else
234
+ raise "Unexpected node is given: #{node.inspect}"
235
+ end
236
+ end
237
+
221
238
  def deconstruct_sendish_and_block_nodes(*nodes)
222
239
  send_node, block_node = nodes.take(2)
223
240
 
@@ -611,18 +611,21 @@ module Steep
611
611
  range = range_for(position, prefix: prefix)
612
612
  context = typing.context_at(line: position.line, column: position.column)
613
613
 
614
- shape = subtyping.builder.shape(
615
- type,
616
- public_only: !include_private,
617
- config: Interface::Builder::Config.new(
618
- self_type: context.self_type,
619
- class_type: context.module_context&.module_type,
620
- instance_type: context.module_context&.instance_type,
621
- variable_bounds: context.variable_context.upper_bounds
622
- )
623
- )
614
+ config =
615
+ if (module_type = context.module_context&.module_type) && (instance_type = context.module_context&.instance_type)
616
+ Interface::Builder::Config.new(
617
+ self_type: context.self_type,
618
+ class_type: module_type,
619
+ instance_type: instance_type,
620
+ variable_bounds: context.variable_context.upper_bounds
621
+ )
622
+ else
623
+ Interface::Builder::Config.new(self_type: context.self_type, variable_bounds: context.variable_context.upper_bounds)
624
+ end
625
+
626
+ if shape = subtyping.builder.shape(type, config)
627
+ shape = shape.public_shape unless include_private
624
628
 
625
- if shape
626
629
  shape.methods.each do |name, method_entry|
627
630
  next if disallowed_method?(name)
628
631
 
@@ -728,13 +731,12 @@ module Steep
728
731
 
729
732
  case call
730
733
  when TypeInference::MethodCall::Typed, TypeInference::MethodCall::Error
734
+ context = typing.context_at(line: position.line, column: position.column)
731
735
  type = call.receiver_type
732
- shape = subtyping.builder.shape(
733
- type,
734
- public_only: !!receiver_node,
735
- config: Interface::Builder::Config.new(self_type: type, class_type: nil, instance_type: nil, variable_bounds: {})
736
- )
737
- if shape
736
+
737
+ config = Interface::Builder::Config.new(self_type: type, variable_bounds: context.variable_context.upper_bounds)
738
+ if shape = subtyping.builder.shape(type, config)
739
+ shape = shape.public_shape if private_send?(call_node)
738
740
  if method = shape.methods[call.method_name]
739
741
  method.method_types.each.with_index do |method_type, i|
740
742
  defn = method_type.method_decls.to_a[0]&.method_def
@@ -19,6 +19,8 @@ module Steep
19
19
  end
20
20
  end
21
21
 
22
+ include NodeHelper
23
+
22
24
  attr_reader :source, :path, :subtyping, :typing, :buffer
23
25
 
24
26
  def env
@@ -103,16 +105,11 @@ module Steep
103
105
  case call
104
106
  when MethodCall::Typed, MethodCall::Error
105
107
  type = call.receiver_type
106
- if type.is_a?(AST::Types::Self)
107
- type = context.self_type
108
- end
108
+ config = Interface::Builder::Config.new(self_type: context.self_type, variable_bounds: context.variable_context.upper_bounds)
109
+
110
+ if shape = subtyping.builder.shape(type, config)
111
+ shape = shape.public_shape if private_send?(node)
109
112
 
110
- shape = subtyping.builder.shape(
111
- type,
112
- public_only: !node.children[0].nil?,
113
- config: Interface::Builder::Config.new(self_type: type, class_type: nil, instance_type: nil, variable_bounds: {})
114
- )
115
- if shape
116
113
  if method = shape.methods[call.method_name]
117
114
  method.method_types.each.with_index do |method_type, i|
118
115
  defn = method_type.method_decls.to_a[0]&.method_def
@@ -175,18 +172,20 @@ module Steep
175
172
  when :splat
176
173
  method_type.type.required_positionals.size + method_type.type.optional_positionals.size if method_type.type.rest_positionals
177
174
  when :kwargs
178
- case argument_nodes[-3].type
179
- when :pair
180
- argname = argument_nodes[-3].children.first.children.first
181
- if method_type.type.required_keywords.key?(argname)
182
- positionals + method_type.type.required_keywords.keys.index(argname).to_i
183
- elsif method_type.type.optional_keywords.key?(argname)
184
- positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.keys.index(argname).to_i
185
- elsif method_type.type.rest_keywords
186
- positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.size
175
+ if argument_nodes[-3]
176
+ case argument_nodes[-3].type
177
+ when :pair
178
+ argname = argument_nodes[-3].children.first.children.first
179
+ if method_type.type.required_keywords.key?(argname)
180
+ positionals + method_type.type.required_keywords.keys.index(argname).to_i
181
+ elsif method_type.type.optional_keywords.key?(argname)
182
+ positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.keys.index(argname).to_i
183
+ elsif method_type.type.rest_keywords
184
+ positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.size
185
+ end
186
+ when :kwsplat
187
+ positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.size if method_type.type.rest_keywords
187
188
  end
188
- when :kwsplat
189
- positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.size if method_type.type.rest_keywords
190
189
  end
191
190
  else
192
191
  pos = (node.children[2...] || raise).index { |c| c.location == argument_nodes[-2].location }.to_i
@@ -1,6 +1,8 @@
1
1
  module Steep
2
2
  module Subtyping
3
3
  class Check
4
+ ABORT_LIMIT = ENV.fetch("STEEP_SUBTYPING_ABORT_LIMIT", 50).to_i
5
+
4
6
  attr_reader :builder
5
7
  attr_reader :cache
6
8
 
@@ -187,6 +189,10 @@ module Steep
187
189
  end
188
190
 
189
191
  def check_type(relation)
192
+ if assumptions.size > ABORT_LIMIT
193
+ return Failure(relation, Result::Failure::LoopAbort.new)
194
+ end
195
+
190
196
  relation.type!
191
197
 
192
198
  Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
@@ -404,14 +410,8 @@ module Steep
404
410
  relation.map {|type|
405
411
  builder.shape(
406
412
  type,
407
- public_only: true,
408
- config: Interface::Builder::Config.new(
409
- self_type: type,
410
- instance_type: instance_type,
411
- class_type: class_type,
412
- variable_bounds: variable_upper_bounds
413
- )
414
- ) or return Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
413
+ Interface::Builder::Config.new(self_type: type, variable_bounds: variable_upper_bounds)
414
+ )&.public_shape() or return Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
415
415
  }
416
416
  )
417
417
  end
@@ -524,14 +524,8 @@ module Steep
524
524
  relation.map {|type|
525
525
  builder.shape(
526
526
  type,
527
- public_only: true,
528
- config: Interface::Builder::Config.new(
529
- self_type: type,
530
- instance_type: instance_type,
531
- class_type: class_type,
532
- variable_bounds: variable_upper_bounds
533
- )
534
- ) or raise
527
+ Interface::Builder::Config.new(self_type: type, variable_bounds: variable_upper_bounds)
528
+ )&.public_shape or raise
535
529
  }
536
530
  )
537
531
  end
@@ -269,6 +269,12 @@ module Steep
269
269
  end
270
270
  end
271
271
 
272
+ class LoopAbort
273
+ def message
274
+ "Detected infinite loop with limit of `#{Check::ABORT_LIMIT}`; specify $STEEP_SUBTYPING_ABORT_LIMIT env var to override the limit."
275
+ end
276
+ end
277
+
272
278
  attr_reader :error
273
279
 
274
280
  def initialize(relation, error)
data/lib/steep/test.rb ADDED
@@ -0,0 +1,9 @@
1
+ Steep.logger.warn(true)
2
+
3
+ # class Steep::Subtyping::Result::All
4
+ # def add(*relations)
5
+ # rel = relations[0] # Relation[T] < Relation::_Subject
6
+ # yield rel # Relation[T] < Relation[_Subject]
7
+ # true
8
+ # end
9
+ # end