sorbet-runtime 0.4.4301 → 0.4.4446

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4caba5123cd2598c381ec8aee684b3ec9d836e82
4
- data.tar.gz: 6a9bbf51e25f0228c8cec2f98565af5721227953
3
+ metadata.gz: 4a800d5e7728111e31a78225eaf32a47c00e3fed
4
+ data.tar.gz: e8546195bf3b79b86484089e66a78966d8cbc9ef
5
5
  SHA512:
6
- metadata.gz: c57c3dca97c35bdb4b7bde004ad20e5a78d0e737f7f2a2a78e047d20feb9513fa5ed216ee083a61222c98616f4764e47b5eb16be096fb040630a666adb8d24a9
7
- data.tar.gz: e88711e3451d9b31013284f577390aa41a85e1f0ad57d639471a1cb2e83da4e7256ebe4c4a6bd4ca73698fc846058791c57364d39f19011438f065cda53b5c7f
6
+ metadata.gz: c2cc3a61f53c8073bcbc091bb5a244059714de8ef38d4f101f5d4d626ab928cfd546a504ce6ef77d1a972b824d0fbfaffdbf11f6fd7e85b6ad8f238131fee3d2
7
+ data.tar.gz: 8db326b0147134aabba33d5500065d5438ed2d362fc86f90ac36c8d53318c228439ace3c4ccb194ec35d8d42991a26a63d0c2ee433867ddbd98ad9710f8abcf6
data/lib/types/_types.rb CHANGED
@@ -176,21 +176,15 @@ module T
176
176
  # Intended to be used to promise sorbet that a given nilable value happens
177
177
  # to contain a non-nil value at this point.
178
178
  #
179
- # sig {params(arg: T.nilable(A), msg: T.nilable(String)).returns(A)}
180
- def self.must(arg, msg=nil)
179
+ # sig {params(arg: T.nilable(A)).returns(A)}
180
+ def self.must(arg)
181
+ return arg if arg
182
+ return arg if arg == false
183
+
181
184
  begin
182
- if msg
183
- if !T.unsafe(msg).is_a?(String)
184
- raise TypeError.new("T.must expects a string as second argument")
185
- end
186
- else
187
- msg = "Passed `nil` into T.must"
188
- end
189
- raise TypeError.new(msg) if arg.nil?
190
- arg
185
+ raise TypeError.new("Passed `nil` into T.must")
191
186
  rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
192
187
  T::Private::ErrorHandler.handle_inline_type_error(e)
193
- arg
194
188
  end
195
189
  end
196
190
 
data/lib/types/boolean.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module T
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # typed: ignore
2
3
 
3
4
  require_relative 'private/methods/_methods'
@@ -2,6 +2,59 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module T::Configuration
5
+ # Announces to Sorbet that we are currently in a test environment, so it
6
+ # should treat any sigs which are marked `.checked(:tests)` as if they were
7
+ # just a normal sig.
8
+ #
9
+ # If this method is not called, sigs marked `.checked(:tests)` will not be
10
+ # checked. In fact, such methods won't even be wrapped--the runtime will put
11
+ # back the original method.
12
+ #
13
+ # Note: Due to the way sigs are evaluated and methods are wrapped, this
14
+ # method MUST be called before any code calls `sig`. This method raises if
15
+ # it has been called too late.
16
+ def self.enable_checking_for_sigs_marked_checked_tests
17
+ T::Private::RuntimeLevels.enable_checking_in_tests
18
+ end
19
+
20
+ # Announce to Sorbet that we would like the final checks to be enabled when
21
+ # including and extending modules. Iff this is not called, then the following
22
+ # example will not raise an error.
23
+ #
24
+ # ```ruby
25
+ # module M
26
+ # extend T::Sig
27
+ # sig(:final) {void}
28
+ # def foo; end
29
+ # end
30
+ # class C
31
+ # include M
32
+ # def foo; end
33
+ # end
34
+ # ```
35
+ def self.enable_final_checks_for_include_extend
36
+ T::Private::Methods.set_final_checks_for_include_extend(true)
37
+ end
38
+
39
+ # Undo the effects of a previous call to
40
+ # `enable_final_checks_for_include_extend`.
41
+ def self.reset_final_checks_for_include_extend
42
+ T::Private::Methods.set_final_checks_for_include_extend(false)
43
+ end
44
+
45
+ # Configure the default checked level for a sig with no explicit `.checked`
46
+ # builder. When unset, the default checked level is `:always`.
47
+ #
48
+ # Note: setting this option is potentially dangerous! Sorbet can't check all
49
+ # code statically. The runtime checks complement the checks that Sorbet does
50
+ # statically, so that methods don't have to guard themselves from being
51
+ # called incorrectly by untyped code.
52
+ #
53
+ # @param [:never, :tests, :always] default_checked_level
54
+ def self.default_checked_level=(default_checked_level)
55
+ T::Private::RuntimeLevels.default_checked_level = default_checked_level
56
+ end
57
+
5
58
  # Set a handler to handle `TypeError`s raised by any in-line type assertions,
6
59
  # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`.
7
60
  #
@@ -84,11 +137,10 @@ module T::Configuration
84
137
  # successfully built, but the built sig is incompatible with other sigs in
85
138
  # some way.
86
139
  #
87
- # By default, sig validation errors cause an exception to be raised. One
88
- # exception is for `generated` sigs, for which a message will be logged
89
- # instead of raising. Setting sig_validation_error_handler to an object that
90
- # implements :call (e.g. proc or lambda) allows users to customize the
91
- # behavior when a method signature's build fails.
140
+ # By default, sig validation errors cause an exception to be raised.
141
+ # Setting sig_validation_error_handler to an object that implements :call
142
+ # (e.g. proc or lambda) allows users to customize the behavior when a method
143
+ # signature's build fails.
92
144
  #
93
145
  # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass
94
146
  # nil to reset to default behavior)
@@ -116,24 +168,7 @@ module T::Configuration
116
168
  end
117
169
 
118
170
  private_class_method def self.sig_validation_error_handler_default(error, opts)
119
- # if this method overrides a generated signature, report that one instead
120
- bad_method = opts[:method]
121
- if !opts[:declaration].generated
122
- super_signature = opts[:super_signature]
123
- raise error if !super_signature&.generated
124
- bad_method = super_signature.method
125
- end
126
-
127
- method_file, method_line = bad_method.source_location
128
- T::Configuration.log_info_handler(
129
- "SIG-DECLARE-FAILED",
130
- {
131
- definition_file: method_file,
132
- definition_line: method_line,
133
- kind: "Delete",
134
- message: error.message,
135
- },
136
- )
171
+ raise error
137
172
  end
138
173
 
139
174
  def self.sig_validation_error_handler(error, opts)
@@ -147,11 +182,9 @@ module T::Configuration
147
182
  # Set a handler for type errors that result from calling a method.
148
183
  #
149
184
  # By default, errors from calling a method cause an exception to be raised.
150
- # One exception is for `generated` sigs, for which a message will be logged
151
- # instead of raising. Setting call_validation_error_handler to an object that
152
- # implements :call (e.g. proc or lambda) allows users to customize the
153
- # behavior when a method is called with invalid parameters, or returns an
154
- # invalid value.
185
+ # Setting call_validation_error_handler to an object that implements :call
186
+ # (e.g. proc or lambda) allows users to customize the behavior when a method
187
+ # is called with invalid parameters, or returns an invalid value.
155
188
  #
156
189
  # @param [Lambda, Proc, Object, nil] value Proc that handles the error
157
190
  # report (pass nil to reset to default behavior)
@@ -180,41 +213,7 @@ module T::Configuration
180
213
  end
181
214
 
182
215
  private_class_method def self.call_validation_error_handler_default(signature, opts)
183
- method_file, method_line = signature.method.source_location
184
- location = opts[:location]
185
- suffix = "Caller: #{location.path}:#{location.lineno}\n" \
186
- "Definition: #{method_file}:#{method_line}"
187
-
188
- error_message = "#{opts[:kind]}#{opts[:name] ? " '#{opts[:name]}'" : ''}: #{opts[:message]}\n#{suffix}"
189
-
190
- if signature.generated
191
- got = opts[:value].class
192
- got = T.unsafe(T::Enumerable[T.untyped]).describe_obj(opts[:value]) if got < Enumerable
193
- T::Configuration.log_info_handler(
194
- "SIG-CHECK-FAILED",
195
- {
196
- caller_file: location.path,
197
- caller_line: location.lineno,
198
- definition_file: method_file,
199
- definition_line: method_line,
200
- kind: opts[:kind],
201
- name: opts[:name],
202
- expected: opts[:type].name,
203
- got: got,
204
- },
205
- )
206
- elsif signature.soft_notify
207
- T::Configuration.soft_assert_handler(
208
- "TypeError: #{error_message}",
209
- {notify: signature.soft_notify}
210
- )
211
- else
212
- begin
213
- raise TypeError.new(error_message)
214
- rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
215
- T::Private::ErrorHandler.handle_inline_type_error(e)
216
- end
217
- end
216
+ raise TypeError.new(opts[:pretty_message])
218
217
  end
219
218
 
220
219
  def self.call_validation_error_handler(signature, opts)
@@ -359,6 +358,26 @@ module T::Configuration
359
358
  @scalar_types || @default_scalar_types
360
359
  end
361
360
 
361
+ # Temporarily disable ruby warnings while executing the given block. This is
362
+ # useful when doing something that would normally cause a warning to be
363
+ # emitted in Ruby verbose mode ($VERBOSE = true).
364
+ #
365
+ # @yield
366
+ #
367
+ def self.without_ruby_warnings
368
+ if $VERBOSE
369
+ begin
370
+ original_verbose = $VERBOSE
371
+ $VERBOSE = false
372
+ yield
373
+ ensure
374
+ $VERBOSE = original_verbose
375
+ end
376
+ else
377
+ yield
378
+ end
379
+ end
380
+
362
381
 
363
382
  private_class_method def self.validate_lambda_given!(value)
364
383
  if !value.nil? && !value.respond_to?(:call)
data/lib/types/generic.rb CHANGED
@@ -13,11 +13,11 @@ module T::Generic
13
13
  self
14
14
  end
15
15
 
16
- def type_member(variance=:invariant, fixed: nil)
16
+ def type_member(variance=:invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
17
17
  T::Types::TypeMember.new(variance) # rubocop:disable PrisonGuard/UseOpusTypesShortcut
18
18
  end
19
19
 
20
- def type_template(variance=:invariant, fixed: nil)
20
+ def type_template(variance=:invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
21
21
  T::Types::TypeTemplate.new(variance) # rubocop:disable PrisonGuard/UseOpusTypesShortcut
22
22
  end
23
23
  end
@@ -18,10 +18,6 @@ module T::Private::Abstract::Declare
18
18
  mod.extend(T::InterfaceWrapper::Helpers)
19
19
 
20
20
  if mod.is_a?(Class)
21
- if mod < T::Struct
22
- raise "#{mod.name} is a subclass of T::Struct and cannot be declared abstract"
23
- end
24
-
25
21
  if type == :interface
26
22
  # Since `interface!` is just `abstract!` with some extra validation, we could technically
27
23
  # allow this, but it's unclear there are good use cases, and it might be confusing.
@@ -32,6 +28,9 @@ module T::Private::Abstract::Declare
32
28
  raise "You must call `abstract!` *before* defining an initialize method"
33
29
  end
34
30
 
31
+ # Don't need to silence warnings via without_ruby_warnings when calling
32
+ # define_method because of the guard above
33
+
35
34
  mod.send(:define_method, :initialize) do |*args, &blk|
36
35
  if self.class == mod
37
36
  raise "#{mod} is declared as abstract; it cannot be instantiated"
@@ -32,7 +32,9 @@ module T::Private::ClassUtils
32
32
 
33
33
  if @overwritten
34
34
  # The original method was overwritten. Overwrite again to restore it.
35
- @mod.send(:define_method, @old_method.name, @old_method) # rubocop:disable PrisonGuard/UsePublicSend
35
+ T::Configuration.without_ruby_warnings do
36
+ @mod.send(:define_method, @old_method.name, @old_method) # rubocop:disable PrisonGuard/UsePublicSend
37
+ end
36
38
  else
37
39
  # The original method was in an ancestor. Restore it by removing the overriding method.
38
40
  @mod.send(:remove_method, @old_method.name) # rubocop:disable PrisonGuard/UsePublicSend
@@ -93,8 +95,10 @@ module T::Private::ClassUtils
93
95
  end
94
96
 
95
97
  overwritten = original_owner == mod
96
- mod.send(:define_method, name, &blk) # rubocop:disable PrisonGuard/UsePublicSend
97
- mod.send(original_visibility, name) # rubocop:disable PrisonGuard/UsePublicSend
98
+ T::Configuration.without_ruby_warnings do
99
+ mod.send(:define_method, name, &blk) # rubocop:disable PrisonGuard/UsePublicSend
100
+ mod.send(original_visibility, name) # rubocop:disable PrisonGuard/UsePublicSend
101
+ end
98
102
  new_method = mod.instance_method(name)
99
103
 
100
104
  ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility)
@@ -11,6 +11,7 @@ class T::Private::DeclState
11
11
  end
12
12
 
13
13
  attr_accessor :active_declaration
14
+ attr_accessor :skip_next_on_method_added
14
15
 
15
16
  def reset!
16
17
  self.active_declaration = nil
@@ -6,23 +6,36 @@ module T::Private::Methods
6
6
  @signatures_by_method = {}
7
7
  @sig_wrappers = {}
8
8
  @sigs_that_raised = {}
9
+ # the info about whether a method is final is not stored in a DeclBuilder nor a Signature, but instead right here.
10
+ # this is because final checks are special:
11
+ # - they are done possibly before any sig block has run.
12
+ # - they are done even if the method being defined doesn't have a sig.
13
+ @final_methods = Set.new
14
+ # if a module directly defines a final method, or includes, extends, or inherits from a module which does so, then it
15
+ # should be in this set.
16
+ @modules_with_final = Set.new
17
+ @old_included_extended = nil
9
18
 
10
19
  ARG_NOT_PROVIDED = Object.new
11
20
  PROC_TYPE = Object.new
12
21
 
13
- DeclarationBlock = Struct.new(:mod, :loc, :blk)
22
+ DeclarationBlock = Struct.new(:mod, :loc, :blk, :final)
14
23
 
15
- def self.declare_sig(mod, &blk)
24
+ def self.declare_sig(mod, arg, &blk)
16
25
  install_hooks(mod)
17
26
 
18
27
  if T::Private::DeclState.current.active_declaration
19
- T::Private::DeclState.current.active_declaration = nil
28
+ T::Private::DeclState.current.reset!
20
29
  raise "You called sig twice without declaring a method inbetween"
21
30
  end
22
31
 
32
+ if !arg.nil? && arg != :final
33
+ raise "Invalid argument to `sig`: #{arg}"
34
+ end
35
+
23
36
  loc = caller_locations(2, 1).first
24
37
 
25
- T::Private::DeclState.current.active_declaration = DeclarationBlock.new(mod, loc, blk)
38
+ T::Private::DeclState.current.active_declaration = DeclarationBlock.new(mod, loc, blk, arg == :final)
26
39
 
27
40
  nil
28
41
  end
@@ -43,8 +56,8 @@ module T::Private::Methods
43
56
  if decl.returns == ARG_NOT_PROVIDED
44
57
  raise "Procs must specify a return type"
45
58
  end
46
- if decl.soft_notify != ARG_NOT_PROVIDED
47
- raise "Procs cannot use .soft"
59
+ if decl.on_failure != ARG_NOT_PROVIDED
60
+ raise "Procs cannot use .on_failure"
48
61
  end
49
62
 
50
63
  if decl.params == ARG_NOT_PROVIDED
@@ -106,15 +119,60 @@ module T::Private::Methods
106
119
  @signatures_by_method[key]
107
120
  end
108
121
 
122
+ # when target includes a module with instance methods source_method_names, ensure there is zero intersection between
123
+ # the final instance methods of target and source_method_names. so, for every m in source_method_names, check if there
124
+ # is already a method defined on one of target_ancestors with the same name that is final.
125
+ def self._check_final_ancestors(target, target_ancestors, source_method_names)
126
+ # use reverse_each to check farther-up ancestors first, for better error messages. we could avoid this if we were on
127
+ # the version of ruby that adds the optional argument to method_defined? that allows you to exclude ancestors.
128
+ target_ancestors.reverse_each do |ancestor|
129
+ source_method_names.each do |method_name|
130
+ # the usage of method_owner_and_name_to_key(ancestor, method_name) instead of
131
+ # method_to_key(ancestor.instance_method(method_name)) is not (just) an optimization, but also required for
132
+ # correctness, since ancestor.method_defined?(method_name) may return true even if method_name is not defined
133
+ # directly on ancestor but instead an ancestor of ancestor.
134
+ if ancestor.method_defined?(method_name) && final_method?(method_owner_and_name_to_key(ancestor, method_name))
135
+ raise(
136
+ "`#{ancestor.name}##{method_name}` was declared as final and cannot be " +
137
+ (target == ancestor ? "redefined" : "overridden in `#{target.name}`")
138
+ )
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ private_class_method def self.add_final_method(method_key)
145
+ @final_methods.add(method_key)
146
+ end
147
+
148
+ private_class_method def self.final_method?(method_key)
149
+ @final_methods.include?(method_key)
150
+ end
151
+
152
+ def self.add_module_with_final(mod)
153
+ @modules_with_final.add(mod)
154
+ end
155
+
156
+ private_class_method def self.module_with_final?(mod)
157
+ @modules_with_final.include?(mod)
158
+ end
159
+
109
160
  # Only public because it needs to get called below inside the replace_method blocks below.
110
161
  def self._on_method_added(hook_mod, method_name, is_singleton_method: false)
111
- current_declaration = T::Private::DeclState.current.active_declaration
112
- return if !current_declaration
113
- T::Private::DeclState.current.reset!
162
+ if T::Private::DeclState.current.skip_next_on_method_added
163
+ T::Private::DeclState.current.skip_next_on_method_added = false
164
+ return
165
+ end
114
166
 
167
+ current_declaration = T::Private::DeclState.current.active_declaration
115
168
  mod = is_singleton_method ? hook_mod.singleton_class : hook_mod
116
169
  original_method = mod.instance_method(method_name)
117
170
 
171
+ _check_final_ancestors(mod, mod.ancestors, [method_name])
172
+
173
+ return if current_declaration.nil?
174
+ T::Private::DeclState.current.reset!
175
+
118
176
  sig_block = lambda do
119
177
  T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration)
120
178
  end
@@ -161,15 +219,16 @@ module T::Private::Methods
161
219
  end
162
220
 
163
221
  new_method = mod.instance_method(method_name)
164
- @sig_wrappers[method_to_key(new_method)] = sig_block
222
+ key = method_to_key(new_method)
223
+ @sig_wrappers[key] = sig_block
224
+ if current_declaration.final
225
+ add_final_method(key)
226
+ add_module_with_final(mod)
227
+ end
165
228
  end
166
229
 
167
230
  def self.sig_error(loc, message)
168
- raise(
169
- ArgumentError.new(
170
- "#{loc.path}:#{loc.lineno}: Error interpreting `sig`:\n #{message}\n\n"
171
- )
172
- )
231
+ raise(ArgumentError.new("#{loc.path}:#{loc.lineno}: Error interpreting `sig`:\n #{message}\n\n"))
173
232
  end
174
233
 
175
234
  # Executes the `sig` block, and converts the resulting Declaration
@@ -224,7 +283,7 @@ module T::Private::Methods
224
283
  bind: current_declaration.bind,
225
284
  mode: current_declaration.mode,
226
285
  check_level: current_declaration.checked,
227
- soft_notify: current_declaration.soft_notify,
286
+ on_failure: current_declaration.on_failure,
228
287
  override_allow_incompatible: current_declaration.override_allow_incompatible,
229
288
  generated: current_declaration.generated,
230
289
  )
@@ -300,21 +359,51 @@ module T::Private::Methods
300
359
  end
301
360
  end
302
361
 
362
+ # the module target is adding the methods from the module source to itself. we need to check that for all instance
363
+ # methods M on source, M is not defined on any of target's ancestors.
364
+ def self._included_extended_impl(target, target_ancestors, source)
365
+ if !module_with_final?(target) && !module_with_final?(source)
366
+ return
367
+ end
368
+ add_module_with_final(target)
369
+ install_hooks(target)
370
+ _check_final_ancestors(target, target_ancestors - source.ancestors, source.instance_methods)
371
+ end
372
+
373
+ def self.set_final_checks_for_include_extend(enable)
374
+ is_enabled = @old_included_extended != nil
375
+ if enable == is_enabled
376
+ return
377
+ end
378
+ if is_enabled
379
+ @old_included_extended.each(&:restore)
380
+ @old_included_extended = nil
381
+ else
382
+ old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg|
383
+ old_included.bind(self).call(arg)
384
+ ::T::Private::Methods._included_extended_impl(arg, arg.ancestors, self)
385
+ end
386
+ old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg|
387
+ old_extended.bind(self).call(arg)
388
+ ::T::Private::Methods._included_extended_impl(arg, arg.singleton_class.ancestors, self)
389
+ end
390
+ @old_included_extended = [old_included, old_extended]
391
+ end
392
+ end
393
+
303
394
  def self.install_hooks(mod)
304
395
  return if @installed_hooks.include?(mod)
305
396
  @installed_hooks << mod
306
397
 
307
398
  if mod.singleton_class?
308
399
  install_singleton_method_added_hook(mod)
309
- install_singleton_method_added_hook(mod.singleton_class)
310
400
  else
311
401
  original_method = T::Private::ClassUtils.replace_method(mod.singleton_class, :method_added) do |name|
312
402
  T::Private::Methods._on_method_added(self, name)
313
403
  original_method.bind(self).call(name)
314
404
  end
315
-
316
- install_singleton_method_added_hook(mod.singleton_class)
317
405
  end
406
+ install_singleton_method_added_hook(mod.singleton_class)
318
407
  end
319
408
 
320
409
  private_class_method def self.install_singleton_method_added_hook(singleton_klass)
@@ -332,8 +421,13 @@ module T::Private::Methods
332
421
  original_singleton_method.bind(attached).call(:singleton_method_added)
333
422
  end
334
423
 
424
+ # use this directly if you don't want/need to box up the method into an object to pass to method_to_key.
425
+ private_class_method def self.method_owner_and_name_to_key(owner, name)
426
+ "#{owner.object_id}##{name}"
427
+ end
428
+
335
429
  private_class_method def self.method_to_key(method)
336
- "#{method.owner.object_id}##{method.name}"
430
+ method_owner_and_name_to_key(method.owner, method.name)
337
431
  end
338
432
 
339
433
  private_class_method def self.key_to_method(key)
@@ -35,9 +35,11 @@ module T::Private::Methods::CallValidation
35
35
  elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
36
36
  create_validator_method(mod, original_method, method_sig, original_visibility)
37
37
  else
38
- # get all the shims out of the way and put back the original method
39
- mod.send(:define_method, method_sig.method_name, original_method)
40
- mod.send(original_visibility, method_sig.method_name)
38
+ T::Configuration.without_ruby_warnings do
39
+ # get all the shims out of the way and put back the original method
40
+ mod.send(:define_method, method_sig.method_name, original_method)
41
+ mod.send(original_visibility, method_sig.method_name)
42
+ end
41
43
  end
42
44
  # Return the newly created method (or the original one if we didn't replace it)
43
45
  mod.instance_method(method_sig.method_name)
@@ -161,18 +163,21 @@ module T::Private::Methods::CallValidation
161
163
  end
162
164
 
163
165
  def self.create_validator_method(mod, original_method, method_sig, original_visibility)
166
+ T::Private::DeclState.current.skip_next_on_method_added = true
164
167
  has_fixed_arity = method_sig.kwarg_types.empty? && !method_sig.has_rest && !method_sig.has_keyrest &&
165
168
  original_method.parameters.all? {|(kind, _name)| kind == :req}
166
169
  all_args_are_simple = method_sig.arg_types.all? {|_name, type| type.is_a?(T::Types::Simple)}
167
170
  has_simple_method_types = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple)
168
171
  has_simple_procedure_types = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void)
169
172
 
170
- if has_fixed_arity && has_simple_method_types && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
171
- create_validator_method_fast(mod, original_method, method_sig)
172
- elsif has_fixed_arity && has_simple_procedure_types && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
173
- create_validator_procedure_fast(mod, original_method, method_sig)
174
- else
175
- create_validator_slow(mod, original_method, method_sig)
173
+ T::Configuration.without_ruby_warnings do
174
+ if has_fixed_arity && has_simple_method_types && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
175
+ create_validator_method_fast(mod, original_method, method_sig)
176
+ elsif has_fixed_arity && has_simple_procedure_types && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
177
+ create_validator_procedure_fast(mod, original_method, method_sig)
178
+ else
179
+ create_validator_slow(mod, original_method, method_sig)
180
+ end
176
181
  end
177
182
  mod.send(original_visibility, method_sig.method_name)
178
183
  end
@@ -1150,10 +1155,16 @@ module T::Private::Methods::CallValidation
1150
1155
  def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0)
1151
1156
  method_sig.mark_failed
1152
1157
  caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0]
1158
+ definition_file, definition_line = method_sig.method.source_location
1159
+
1160
+ pretty_message = "#{kind}#{name ? " '#{name}'" : ''}: #{error_message}\n" \
1161
+ "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" \
1162
+ "Definition: #{definition_file}:#{definition_line}"
1153
1163
 
1154
1164
  T::Private::ErrorHandler.handle_call_validation_error(
1155
1165
  method_sig,
1156
1166
  message: error_message,
1167
+ pretty_message: pretty_message,
1157
1168
  kind: kind,
1158
1169
  name: name,
1159
1170
  type: type,