sorbet-runtime 0.4.4667 → 0.5.6189

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/lib/sorbet-runtime.rb +15 -3
  3. data/lib/types/_types.rb +26 -17
  4. data/lib/types/boolean.rb +1 -1
  5. data/lib/types/compatibility_patches.rb +65 -10
  6. data/lib/types/configuration.rb +93 -7
  7. data/lib/types/enum.rb +371 -0
  8. data/lib/types/generic.rb +2 -2
  9. data/lib/types/interface_wrapper.rb +4 -4
  10. data/lib/types/non_forcing_constants.rb +61 -0
  11. data/lib/types/private/abstract/data.rb +2 -2
  12. data/lib/types/private/abstract/declare.rb +3 -0
  13. data/lib/types/private/abstract/validate.rb +7 -7
  14. data/lib/types/private/casts.rb +27 -0
  15. data/lib/types/private/class_utils.rb +8 -5
  16. data/lib/types/private/methods/_methods.rb +80 -28
  17. data/lib/types/private/methods/call_validation.rb +5 -47
  18. data/lib/types/private/methods/decl_builder.rb +14 -56
  19. data/lib/types/private/methods/modes.rb +5 -7
  20. data/lib/types/private/methods/signature.rb +32 -18
  21. data/lib/types/private/methods/signature_validation.rb +29 -35
  22. data/lib/types/private/retry.rb +10 -0
  23. data/lib/types/private/sealed.rb +21 -1
  24. data/lib/types/private/types/type_alias.rb +31 -0
  25. data/lib/types/private/types/void.rb +4 -3
  26. data/lib/types/profile.rb +5 -1
  27. data/lib/types/props/_props.rb +3 -7
  28. data/lib/types/props/constructor.rb +29 -9
  29. data/lib/types/props/custom_type.rb +51 -27
  30. data/lib/types/props/decorator.rb +248 -405
  31. data/lib/types/props/generated_code_validation.rb +268 -0
  32. data/lib/types/props/has_lazily_specialized_methods.rb +92 -0
  33. data/lib/types/props/optional.rb +37 -41
  34. data/lib/types/props/plugin.rb +23 -1
  35. data/lib/types/props/pretty_printable.rb +3 -3
  36. data/lib/types/props/private/apply_default.rb +170 -0
  37. data/lib/types/props/private/deserializer_generator.rb +165 -0
  38. data/lib/types/props/private/parser.rb +32 -0
  39. data/lib/types/props/private/serde_transform.rb +186 -0
  40. data/lib/types/props/private/serializer_generator.rb +77 -0
  41. data/lib/types/props/private/setter_factory.rb +139 -0
  42. data/lib/types/props/serializable.rb +137 -192
  43. data/lib/types/props/type_validation.rb +19 -6
  44. data/lib/types/props/utils.rb +3 -7
  45. data/lib/types/props/weak_constructor.rb +51 -14
  46. data/lib/types/sig.rb +6 -6
  47. data/lib/types/types/attached_class.rb +37 -0
  48. data/lib/types/types/base.rb +26 -2
  49. data/lib/types/types/fixed_array.rb +28 -2
  50. data/lib/types/types/fixed_hash.rb +11 -10
  51. data/lib/types/types/intersection.rb +6 -0
  52. data/lib/types/types/noreturn.rb +4 -0
  53. data/lib/types/types/self_type.rb +4 -0
  54. data/lib/types/types/simple.rb +22 -1
  55. data/lib/types/types/t_enum.rb +38 -0
  56. data/lib/types/types/type_parameter.rb +1 -1
  57. data/lib/types/types/type_variable.rb +1 -1
  58. data/lib/types/types/typed_array.rb +7 -2
  59. data/lib/types/types/typed_enumerable.rb +28 -17
  60. data/lib/types/types/typed_enumerator.rb +7 -2
  61. data/lib/types/types/typed_hash.rb +8 -3
  62. data/lib/types/types/typed_range.rb +7 -2
  63. data/lib/types/types/typed_set.rb +7 -2
  64. data/lib/types/types/union.rb +37 -5
  65. data/lib/types/types/untyped.rb +4 -0
  66. data/lib/types/utils.rb +43 -11
  67. metadata +103 -11
  68. data/lib/types/private/error_handler.rb +0 -0
  69. data/lib/types/runtime_profiled.rb +0 -24
  70. data/lib/types/types/opus_enum.rb +0 -33
@@ -14,10 +14,10 @@ module T::Generic
14
14
  end
15
15
 
16
16
  def type_member(variance=:invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
17
- T::Types::TypeMember.new(variance) # rubocop:disable PrisonGuard/UseOpusTypesShortcut
17
+ T::Types::TypeMember.new(variance)
18
18
  end
19
19
 
20
20
  def type_template(variance=:invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
21
- T::Types::TypeTemplate.new(variance) # rubocop:disable PrisonGuard/UseOpusTypesShortcut
21
+ T::Types::TypeTemplate.new(variance)
22
22
  end
23
23
  end
@@ -83,11 +83,11 @@ class T::InterfaceWrapper
83
83
  end
84
84
  end
85
85
 
86
- def kind_of?(other) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
86
+ def kind_of?(other)
87
87
  is_a?(other)
88
88
  end
89
89
 
90
- def is_a?(other) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
90
+ def is_a?(other)
91
91
  if !other.is_a?(Module)
92
92
  raise TypeError.new("class or module required")
93
93
  end
@@ -99,13 +99,13 @@ class T::InterfaceWrapper
99
99
 
100
100
  # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't
101
101
  # want anyone else (besides dynamic_cast) calling it.
102
- def __target_obj_DO_NOT_USE
102
+ def __target_obj_DO_NOT_USE # rubocop:disable Naming/MethodName
103
103
  @target_obj
104
104
  end
105
105
 
106
106
  # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't
107
107
  # want anyone else (besides wrapped_dynamic_cast) calling it.
108
- def __interface_mod_DO_NOT_USE
108
+ def __interface_mod_DO_NOT_USE # rubocop:disable Naming/MethodName
109
109
  @interface_mod
110
110
  end
111
111
 
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module T::NonForcingConstants
5
+ # NOTE: This method is documented on the RBI in Sorbet's payload, so that it
6
+ # shows up in the hover/completion documentation via LSP.
7
+ T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String, package: T.nilable(String)).returns(T::Boolean)}
8
+ def self.non_forcing_is_a?(val, klass, package: nil)
9
+ # TODO(gdritter): once we have a runtime implementation of
10
+ # packages, we'll need to actually handle the `package` argument
11
+ # here.
12
+ method_name = "T::NonForcingConstants.non_forcing_is_a?"
13
+ if klass.empty?
14
+ raise ArgumentError.new("The string given to `#{method_name}` must not be empty")
15
+ end
16
+
17
+ current_klass = T.let(nil, T.nilable(Module))
18
+ current_prefix = T.let(nil, T.nilable(String))
19
+
20
+ parts = klass.split('::')
21
+ parts.each do |part|
22
+ if current_klass.nil?
23
+ # First iteration
24
+ if part != "" && package.nil?
25
+ # if we've supplied a package, we're probably running in
26
+ # package mode, which means absolute references are
27
+ # meaningless
28
+ raise ArgumentError.new("The string given to `#{method_name}` must be an absolute constant reference that starts with `::`")
29
+ end
30
+
31
+ current_klass = Object
32
+ current_prefix = ''
33
+
34
+ # if this had a :: prefix, then there's no more loading to
35
+ # do---skip to the next one
36
+ next if part == ""
37
+ end
38
+
39
+ if current_klass.autoload?(part)
40
+ # There's an autoload registered for that constant, which means it's not
41
+ # yet loaded. `value` can't be an instance of something not yet loaded.
42
+ return false
43
+ end
44
+
45
+ # Sorbet guarantees that the string is an absolutely resolved name.
46
+ search_inheritance_chain = false
47
+ if !current_klass.const_defined?(part, search_inheritance_chain)
48
+ return false
49
+ end
50
+
51
+ current_klass = current_klass.const_get(part)
52
+ current_prefix = "#{current_prefix}::#{part}"
53
+
54
+ if !Module.===(current_klass)
55
+ raise ArgumentError.new("#{current_prefix} is not a class or module")
56
+ end
57
+ end
58
+
59
+ current_klass.===(val)
60
+ end
61
+ end
@@ -12,11 +12,11 @@
12
12
  # modules that override the `hash` method with something completely broken.
13
13
  module T::Private::Abstract::Data
14
14
  def self.get(mod, key)
15
- mod.instance_variable_get("@opus_abstract__#{key}") # rubocop:disable PrisonGuard/NoLurkyInstanceVariableAccess
15
+ mod.instance_variable_get("@opus_abstract__#{key}")
16
16
  end
17
17
 
18
18
  def self.set(mod, key, value)
19
- mod.instance_variable_set("@opus_abstract__#{key}", value) # rubocop:disable PrisonGuard/NoLurkyInstanceVariableAccess
19
+ mod.instance_variable_set("@opus_abstract__#{key}", value)
20
20
  end
21
21
 
22
22
  def self.key?(mod, key)
@@ -40,6 +40,9 @@ module T::Private::Abstract::Declare
40
40
  end
41
41
  super(*args, &blk)
42
42
  end
43
+ if mod.respond_to?(:ruby2_keywords, true)
44
+ mod.send(:ruby2_keywords, :initialize)
45
+ end
43
46
  end
44
47
  end
45
48
  end
@@ -61,7 +61,7 @@ module T::Private::Abstract::Validate
61
61
  # In that case, get its untyped signature.
62
62
  implementation_signature ||= Methods::Signature.new_untyped(
63
63
  method: implementation_method,
64
- mode: Methods::Modes.implementation
64
+ mode: Methods::Modes.override
65
65
  )
66
66
  SignatureValidation.validate_override_shape(implementation_signature, abstract_signature)
67
67
  SignatureValidation.validate_override_types(implementation_signature, abstract_signature)
@@ -111,16 +111,16 @@ module T::Private::Abstract::Validate
111
111
  end
112
112
 
113
113
  private_class_method def self.describe_method(method, show_owner: true)
114
- if method.source_location
115
- loc = method.source_location.join(':')
114
+ loc = if method.source_location
115
+ method.source_location.join(':')
116
116
  else
117
- loc = "<unknown location>"
117
+ "<unknown location>"
118
118
  end
119
119
 
120
- if show_owner
121
- owner = " declared in #{method.owner}"
120
+ owner = if show_owner
121
+ " declared in #{method.owner}"
122
122
  else
123
- owner = ""
123
+ ""
124
124
  end
125
125
 
126
126
  " * `#{method.name}`#{owner} at #{loc}"
@@ -2,6 +2,14 @@
2
2
  # typed: false
3
3
 
4
4
  module T::Private
5
+ # Dynamically confirm that `value` is recursively a valid value of
6
+ # type `type`, including recursively through collections. Note that
7
+ # in some cases this runtime check can be very expensive, especially
8
+ # with large collections of objects.
9
+ def self.check_type_recursive!(value, type)
10
+ T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!")
11
+ end
12
+
5
13
  module Casts
6
14
  def self.cast(value, type, cast_method:)
7
15
  begin
@@ -18,5 +26,24 @@ module T::Private
18
26
  value
19
27
  end
20
28
  end
29
+
30
+ # there's a lot of shared logic with the above one, but factoring
31
+ # it out like this makes it easier to hopefully one day delete
32
+ # this one
33
+ def self.cast_recursive(value, type, cast_method:)
34
+ begin
35
+ error = T::Utils.coerce(type).error_message_for_obj_recursive(value)
36
+ return value unless error
37
+
38
+ caller_loc = T.must(caller_locations(2..2)).first
39
+
40
+ suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}"
41
+
42
+ raise TypeError.new("#{cast_method}: #{error}\n#{suffix}")
43
+ rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
44
+ T::Configuration.inline_type_error_handler(e)
45
+ value
46
+ end
47
+ end
21
48
  end
22
49
  end
@@ -33,16 +33,16 @@ module T::Private::ClassUtils
33
33
  if @overwritten
34
34
  # The original method was overwritten. Overwrite again to restore it.
35
35
  T::Configuration.without_ruby_warnings do
36
- @mod.send(:define_method, @old_method.name, @old_method) # rubocop:disable PrisonGuard/UsePublicSend
36
+ @mod.send(:define_method, @old_method.name, @old_method)
37
37
  end
38
38
  else
39
39
  # The original method was in an ancestor. Restore it by removing the overriding method.
40
- @mod.send(:remove_method, @old_method.name) # rubocop:disable PrisonGuard/UsePublicSend
40
+ @mod.send(:remove_method, @old_method.name)
41
41
  end
42
42
 
43
43
  # Restore the visibility. Note that we need to do this even when we call remove_method
44
44
  # above, because the module may have set custom visibility for a method it inherited.
45
- @mod.send(@visibility, @old_method.name) # rubocop:disable PrisonGuard/UsePublicSend
45
+ @mod.send(@visibility, @old_method.name)
46
46
 
47
47
  nil
48
48
  end
@@ -97,10 +97,13 @@ module T::Private::ClassUtils
97
97
  overwritten = original_owner == mod
98
98
  T::Configuration.without_ruby_warnings do
99
99
  T::Private::DeclState.current.without_on_method_added do
100
- mod.send(:define_method, name, &blk) # rubocop:disable PrisonGuard/UsePublicSend
100
+ mod.send(:define_method, name, &blk)
101
+ if blk.arity < 0 && mod.respond_to?(:ruby2_keywords, true)
102
+ mod.send(:ruby2_keywords, name)
103
+ end
101
104
  end
102
105
  end
103
- mod.send(original_visibility, name) # rubocop:disable PrisonGuard/UsePublicSend
106
+ mod.send(original_visibility, name)
104
107
  new_method = mod.instance_method(name)
105
108
 
106
109
  ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility)
@@ -72,7 +72,7 @@ module T::Private::Methods
72
72
  decl.params = {}
73
73
  end
74
74
 
75
- T::Types::Proc.new(decl.params, decl.returns) # rubocop:disable PrisonGuard/UseOpusTypesShortcut
75
+ T::Types::Proc.new(decl.params, decl.returns)
76
76
  end
77
77
 
78
78
  # See docs at T::Utils.register_forwarder.
@@ -142,7 +142,10 @@ module T::Private::Methods
142
142
  # method_to_key(ancestor.instance_method(method_name)) is not (just) an optimization, but also required for
143
143
  # correctness, since ancestor.method_defined?(method_name) may return true even if method_name is not defined
144
144
  # directly on ancestor but instead an ancestor of ancestor.
145
- if ancestor.method_defined?(method_name) && final_method?(method_owner_and_name_to_key(ancestor, method_name))
145
+ if (ancestor.method_defined?(method_name) ||
146
+ ancestor.private_method_defined?(method_name) ||
147
+ ancestor.protected_method_defined?(method_name)) &&
148
+ final_method?(method_owner_and_name_to_key(ancestor, method_name))
146
149
  raise(
147
150
  "The method `#{method_name}` on #{ancestor} was declared as final and cannot be " +
148
151
  (target == ancestor ? "redefined" : "overridden in #{target}")
@@ -190,7 +193,7 @@ module T::Private::Methods
190
193
 
191
194
  if method_name == :method_added || method_name == :singleton_method_added
192
195
  raise(
193
- "Putting a `sig` on `#{method_name}` is not supported" +
196
+ "Putting a `sig` on `#{method_name}` is not supported" \
194
197
  " (sorbet-runtime uses this method internally to perform `sig` validation logic)"
195
198
  )
196
199
  end
@@ -206,22 +209,12 @@ module T::Private::Methods
206
209
  # (or unwrap back to the original method).
207
210
  new_method = nil
208
211
  T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk|
209
- if !T::Private::Methods.has_sig_block_for_method(new_method)
210
- # This should only happen if the user used alias_method to grab a handle
211
- # to the original pre-unwound `sig` method. I guess we'll just proxy the
212
- # call forever since we don't know who is holding onto this handle to
213
- # replace it.
214
- new_new_method = mod.instance_method(method_name)
215
- if new_method == new_new_method
216
- raise "`sig` not present for method `#{method_name}` but you're trying to run it anyways. " \
217
- "This should only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but that clearly isn't what you are doing. " \
218
- "Maybe look to see if an exception was thrown in your `sig` lambda or somehow else your `sig` wasn't actually applied to the method. " \
219
- "Contact #dev-productivity if you're really stuck."
220
- end
221
- return new_new_method.bind(self).call(*args, &blk)
222
- end
223
-
224
- method_sig = T::Private::Methods.run_sig_block_for_method(new_method)
212
+ method_sig = T::Private::Methods.maybe_run_sig_block_for_method(new_method)
213
+ method_sig ||= T::Private::Methods._handle_missing_method_signature(
214
+ self,
215
+ original_method,
216
+ __callee__,
217
+ )
225
218
 
226
219
  # Should be the same logic as CallValidation.wrap_method_if_needed but we
227
220
  # don't want that extra layer of indirection in the callstack
@@ -252,6 +245,43 @@ module T::Private::Methods
252
245
  end
253
246
  end
254
247
 
248
+ def self._handle_missing_method_signature(receiver, original_method, callee)
249
+ method_sig = T::Private::Methods.signature_for_method(original_method)
250
+ if !method_sig
251
+ raise "`sig` not present for method `#{callee}` on #{receiver.inspect} but you're trying to run it anyways. " \
252
+ "This should only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but that clearly isn't what you are doing. " \
253
+ "Maybe look to see if an exception was thrown in your `sig` lambda or somehow else your `sig` wasn't actually applied to the method."
254
+ end
255
+
256
+ if receiver.class <= original_method.owner
257
+ receiving_class = receiver.class
258
+ elsif receiver.singleton_class <= original_method.owner
259
+ receiving_class = receiver.singleton_class
260
+ elsif receiver.is_a?(Module) && receiver <= original_method.owner
261
+ receiving_class = receiver
262
+ else
263
+ raise "#{receiver} is not related to #{original_method} - how did we get here?"
264
+ end
265
+
266
+ # Check for a case where `alias` or `alias_method` was called for a
267
+ # method which had already had a `sig` applied. In that case, we want
268
+ # to avoid hitting this slow path again, by moving to a faster validator
269
+ # just like we did or will for the original method.
270
+ #
271
+ # If this isn't an `alias` or `alias_method` case, we're probably in the
272
+ # middle of some metaprogramming using a Method object, e.g. a pattern like
273
+ # `arr.map(&method(:foo))`. There's nothing really we can do to optimize
274
+ # that here.
275
+ receiving_method = receiving_class.instance_method(callee)
276
+ if receiving_method != original_method && receiving_method.original_name == original_method.name
277
+ aliasing_mod = receiving_method.owner
278
+ method_sig = method_sig.as_alias(callee)
279
+ unwrap_method(aliasing_mod, method_sig, original_method)
280
+ end
281
+
282
+ method_sig
283
+ end
284
+
255
285
  # Executes the `sig` block, and converts the resulting Declaration
256
286
  # to a Signature.
257
287
  def self.run_sig(hook_mod, method_name, original_method, declaration_block)
@@ -270,7 +300,7 @@ module T::Private::Methods
270
300
  Signature.new_untyped(method: original_method)
271
301
  end
272
302
 
273
- unwrap_method(hook_mod, signature, original_method)
303
+ unwrap_method(signature.method.owner, signature, original_method)
274
304
  signature
275
305
  end
276
306
 
@@ -284,8 +314,12 @@ module T::Private::Methods
284
314
 
285
315
  def self.build_sig(hook_mod, method_name, original_method, current_declaration, loc)
286
316
  begin
287
- # We allow `sig` in the current module's context (normal case) and inside `class << self`
288
- if hook_mod != current_declaration.mod && hook_mod.singleton_class != current_declaration.mod
317
+ # We allow `sig` in the current module's context (normal case) and
318
+ if hook_mod != current_declaration.mod &&
319
+ # inside `class << self`, and
320
+ hook_mod.singleton_class != current_declaration.mod &&
321
+ # on `self` at the top level of a file
322
+ current_declaration.mod != TOP_SELF
289
323
  raise "A method (#{method_name}) is being added on a different class/module (#{hook_mod}) than the " \
290
324
  "last call to `sig` (#{current_declaration.mod}). Make sure each call " \
291
325
  "to `sig` is immediately followed by a method definition on the same " \
@@ -302,7 +336,6 @@ module T::Private::Methods
302
336
  check_level: current_declaration.checked,
303
337
  on_failure: current_declaration.on_failure,
304
338
  override_allow_incompatible: current_declaration.override_allow_incompatible,
305
- generated: current_declaration.generated,
306
339
  )
307
340
 
308
341
  SignatureValidation.validate(signature)
@@ -323,8 +356,8 @@ module T::Private::Methods
323
356
  end
324
357
  end
325
358
 
326
- def self.unwrap_method(hook_mod, signature, original_method)
327
- maybe_wrapped_method = CallValidation.wrap_method_if_needed(signature.method.owner, signature, original_method)
359
+ def self.unwrap_method(mod, signature, original_method)
360
+ maybe_wrapped_method = CallValidation.wrap_method_if_needed(mod, signature, original_method)
328
361
  @signatures_by_method[method_to_key(maybe_wrapped_method)] = signature
329
362
  end
330
363
 
@@ -377,7 +410,7 @@ module T::Private::Methods
377
410
  def self.run_all_sig_blocks
378
411
  loop do
379
412
  break if @sig_wrappers.empty?
380
- key, _ = @sig_wrappers.first
413
+ key, = @sig_wrappers.first
381
414
  run_sig_block_for_key(key)
382
415
  end
383
416
  end
@@ -394,7 +427,7 @@ module T::Private::Methods
394
427
  end
395
428
 
396
429
  def self.set_final_checks_on_hooks(enable)
397
- is_enabled = @old_hooks != nil
430
+ is_enabled = !@old_hooks.nil?
398
431
  if enable == is_enabled
399
432
  return
400
433
  end
@@ -436,6 +469,20 @@ module T::Private::Methods
436
469
  return if @installed_hooks.include?(mod)
437
470
  @installed_hooks << mod
438
471
 
472
+ if mod == TOP_SELF
473
+ # self at the top-level of a file is weirdly special in Ruby
474
+ # The Ruby VM on startup creates an `Object.new` and stashes it.
475
+ # Unlike when we're using sig inside a module, `self` is actually a
476
+ # normal object, not an instance of Module.
477
+ #
478
+ # Thus we can't ask things like mod.singleton_class? (since that's
479
+ # defined only on Module, not on Object) and even if we could, the places
480
+ # where we need to install the hooks are special.
481
+ mod.extend(SingletonMethodHooks) # def self.foo; end (at top level)
482
+ Object.extend(MethodHooks) # def foo; end (at top level)
483
+ return
484
+ end
485
+
439
486
  if mod.singleton_class?
440
487
  mod.include(SingletonMethodHooks)
441
488
  else
@@ -455,7 +502,12 @@ module T::Private::Methods
455
502
 
456
503
  private_class_method def self.key_to_method(key)
457
504
  id, name = key.split("#")
458
- obj = ObjectSpace._id2ref(id.to_i) # rubocop:disable PrisonGuard/NoDynamicConstAccess
505
+ obj = ObjectSpace._id2ref(id.to_i)
459
506
  obj.instance_method(name)
460
507
  end
461
508
  end
509
+
510
+ # This has to be here, and can't be nested inside `T::Private::Methods`,
511
+ # because the value of `self` depends on lexical (nesting) scope, and we
512
+ # specifically need a reference to the file-level self, i.e. `main:Object`
513
+ T::Private::Methods::TOP_SELF = self
@@ -51,10 +51,6 @@ module T::Private::Methods::CallValidation
51
51
  # This method is called for every `sig`. It's critical to keep it fast and
52
52
  # reduce number of allocations that happen here.
53
53
 
54
- if method_sig.ever_failed && method_sig.generated
55
- return original_method.bind(instance).call(*args, &blk)
56
- end
57
-
58
54
  T::Profile.typecheck_sample_attempts -= 1
59
55
  should_sample = T::Profile.typecheck_sample_attempts == 0
60
56
  if should_sample
@@ -189,6 +185,9 @@ module T::Private::Methods::CallValidation
189
185
  mod.send(:define_method, method_sig.method_name) do |*args, &blk|
190
186
  CallValidation.validate_call(self, original_method, method_sig, args, blk)
191
187
  end
188
+ if mod.respond_to?(:ruby2_keywords, true)
189
+ mod.send(:ruby2_keywords, method_sig.method_name)
190
+ end
192
191
  end
193
192
 
194
193
  def self.create_validator_method_fast(mod, original_method, method_sig)
@@ -196,7 +195,7 @@ module T::Private::Methods::CallValidation
196
195
  raise "Should have used create_validator_procedure_fast"
197
196
  end
198
197
  # trampoline to reduce stack frame size
199
- if method_sig.arg_types.length == 0
198
+ if method_sig.arg_types.empty?
200
199
  create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type)
201
200
  elsif method_sig.arg_types.length == 1
202
201
  create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type,
@@ -252,10 +251,6 @@ module T::Private::Methods::CallValidation
252
251
  T::Profile.typecheck_duration += (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t1)
253
252
  end
254
253
 
255
- if method_sig.ever_failed && method_sig.generated
256
- return original_method.bind(self).call(&blk)
257
- end
258
-
259
254
  # The following line breaks are intentional to show nice pry message
260
255
 
261
256
 
@@ -303,10 +298,6 @@ module T::Private::Methods::CallValidation
303
298
  # reduce number of allocations that happen here.
304
299
  # This method is a manually sped-up version of more general code in `validate_call`
305
300
 
306
- if method_sig.ever_failed && method_sig.generated
307
- return original_method.bind(self).call(arg0, &blk)
308
- end
309
-
310
301
  T::Profile.typecheck_sample_attempts -= 1
311
302
  should_sample = T::Profile.typecheck_sample_attempts == 0
312
303
  if should_sample
@@ -392,10 +383,6 @@ module T::Private::Methods::CallValidation
392
383
  # reduce number of allocations that happen here.
393
384
  # This method is a manually sped-up version of more general code in `validate_call`
394
385
 
395
- if method_sig.ever_failed && method_sig.generated
396
- return original_method.bind(self).call(arg0, arg1, &blk)
397
- end
398
-
399
386
  T::Profile.typecheck_sample_attempts -= 1
400
387
  should_sample = T::Profile.typecheck_sample_attempts == 0
401
388
  if should_sample
@@ -493,10 +480,6 @@ module T::Private::Methods::CallValidation
493
480
  # reduce number of allocations that happen here.
494
481
  # This method is a manually sped-up version of more general code in `validate_call`
495
482
 
496
- if method_sig.ever_failed && method_sig.generated
497
- return original_method.bind(self).call(arg0, arg1, arg2, &blk)
498
- end
499
-
500
483
  T::Profile.typecheck_sample_attempts -= 1
501
484
  should_sample = T::Profile.typecheck_sample_attempts == 0
502
485
  if should_sample
@@ -607,10 +590,6 @@ module T::Private::Methods::CallValidation
607
590
  # reduce number of allocations that happen here.
608
591
  # This method is a manually sped-up version of more general code in `validate_call`
609
592
 
610
- if method_sig.ever_failed && method_sig.generated
611
- return original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk)
612
- end
613
-
614
593
  T::Profile.typecheck_sample_attempts -= 1
615
594
  should_sample = T::Profile.typecheck_sample_attempts == 0
616
595
  if should_sample
@@ -729,7 +708,7 @@ module T::Private::Methods::CallValidation
729
708
 
730
709
  def self.create_validator_procedure_fast(mod, original_method, method_sig)
731
710
  # trampoline to reduce stack frame size
732
- if method_sig.arg_types.length == 0
711
+ if method_sig.arg_types.empty?
733
712
  create_validator_procedure_fast0(mod, original_method, method_sig)
734
713
  elsif method_sig.arg_types.length == 1
735
714
  create_validator_procedure_fast1(mod, original_method, method_sig,
@@ -760,10 +739,6 @@ module T::Private::Methods::CallValidation
760
739
  # reduce number of allocations that happen here.
761
740
  # This method is a manually sped-up version of more general code in `validate_call`
762
741
 
763
- if method_sig.ever_failed && method_sig.generated
764
- return original_method.bind(self).call(&blk)
765
- end
766
-
767
742
  T::Profile.typecheck_sample_attempts -= 1
768
743
  should_sample = T::Profile.typecheck_sample_attempts == 0
769
744
  if should_sample
@@ -817,10 +792,6 @@ module T::Private::Methods::CallValidation
817
792
  # reduce number of allocations that happen here.
818
793
  # This method is a manually sped-up version of more general code in `validate_call`
819
794
 
820
- if method_sig.ever_failed && method_sig.generated
821
- return original_method.bind(self).call(arg0, &blk)
822
- end
823
-
824
795
  T::Profile.typecheck_sample_attempts -= 1
825
796
  should_sample = T::Profile.typecheck_sample_attempts == 0
826
797
  if should_sample
@@ -884,10 +855,6 @@ module T::Private::Methods::CallValidation
884
855
  # reduce number of allocations that happen here.
885
856
  # This method is a manually sped-up version of more general code in `validate_call`
886
857
 
887
- if method_sig.ever_failed && method_sig.generated
888
- return original_method.bind(self).call(arg0, arg1, &blk)
889
- end
890
-
891
858
  T::Profile.typecheck_sample_attempts -= 1
892
859
  should_sample = T::Profile.typecheck_sample_attempts == 0
893
860
  if should_sample
@@ -964,10 +931,6 @@ module T::Private::Methods::CallValidation
964
931
  # reduce number of allocations that happen here.
965
932
  # This method is a manually sped-up version of more general code in `validate_call`
966
933
 
967
- if method_sig.ever_failed && method_sig.generated
968
- return original_method.bind(self).call(arg0, arg1, arg2, &blk)
969
- end
970
-
971
934
  T::Profile.typecheck_sample_attempts -= 1
972
935
  should_sample = T::Profile.typecheck_sample_attempts == 0
973
936
  if should_sample
@@ -1057,10 +1020,6 @@ module T::Private::Methods::CallValidation
1057
1020
  # reduce number of allocations that happen here.
1058
1021
  # This method is a manually sped-up version of more general code in `validate_call`
1059
1022
 
1060
- if method_sig.ever_failed && method_sig.generated
1061
- return original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk)
1062
- end
1063
-
1064
1023
  T::Profile.typecheck_sample_attempts -= 1
1065
1024
  should_sample = T::Profile.typecheck_sample_attempts == 0
1066
1025
  if should_sample
@@ -1156,7 +1115,6 @@ module T::Private::Methods::CallValidation
1156
1115
  end
1157
1116
 
1158
1117
  def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0)
1159
- method_sig.mark_failed
1160
1118
  caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0]
1161
1119
  definition_file, definition_line = method_sig.method.source_location
1162
1120