sorbet-runtime 0.6.12872 → 0.6.13192

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
  SHA256:
3
- metadata.gz: f1df82030d7eef7b4581bd982da33dafd6667515045b5e32e36d95d2cd96e876
4
- data.tar.gz: c6b5c03495c971851b599f2465ce86a983a23b7455b9766755b77da9916b2d38
3
+ metadata.gz: bf43d3cf4e297c8c2c814618b558777e99dad15ee9fdedaf1275adac6303b1ab
4
+ data.tar.gz: 9b454b18a90066a60aef190a683699dae158bf6e0d42be29b4314e3e5a28a072
5
5
  SHA512:
6
- metadata.gz: 1491c37794b1e008c76728181aa3fdeb4fa7ac16c995d9c9d8477d7b5a6bd557c921781097d07f060b378de14648050cd773b35735ad46129fe074b888495fe4
7
- data.tar.gz: 84d80bada939f468b9580708a11a63f3b08ab61c411b79d202afe294beab896f886213aa044d718170fcabced529be555ee08083be70b6f85f66ea61421ac6c2
6
+ metadata.gz: b5e5e921d5a506dabd5fe96e434a73723ec8105ac8f4d554379f2e82f265e965dfbeed04b04b1875f8f35520467bb35d41f8baf8dc6558d07068e1ece3f55af6
7
+ data.tar.gz: 145f14e022976650ccbed8a8abe9398970d687759833650185156e4e4156d91b7fd7b54ade90a86c7be2a916b608880ae739d1d8473e629c29714c1330a33b6b
data/lib/types/helpers.rb CHANGED
@@ -4,8 +4,6 @@
4
4
  # Use as a mixin with extend (`extend T::Helpers`).
5
5
  # Docs at https://sorbet.org/docs/
6
6
  module T::Helpers
7
- extend T::Sig
8
-
9
7
  Private = T::Private
10
8
 
11
9
  ### Class/Module Helpers ###
@@ -27,7 +27,7 @@ module T::Private::Abstract::Hooks
27
27
  # `self` may not actually be abstract -- it could be a concrete class that inherited from an
28
28
  # abstract class. We only need to check this in `inherited` because, for modules being included
29
29
  # or extended, the concrete ones won't have these hooks at all. This is just an optimization.
30
- return if !T::AbstractUtils.abstract_module?(self)
30
+ return if !T::AbstractUtils.abstract_module?(T.unsafe(self))
31
31
 
32
32
  T::Private::Abstract::Data.set(self, :last_used_by, other)
33
33
  end
@@ -3,61 +3,14 @@
3
3
 
4
4
  # Cut down version of Chalk::Tools::ClassUtils with only :replace_method functionality.
5
5
  # Extracted to a separate namespace so the type system can be used standalone.
6
+ #
7
+ # Note: the functionality to "restore" a method was removed, because it is no
8
+ # longer being used by sorbet-runtime. Restoring a method requires care--if you
9
+ # need to reintroduce this functionality, consult the git history for how to do
10
+ # it safely.
6
11
  module T::Private::ClassUtils
7
- class ReplacedMethod
8
- def initialize(mod, old_method, new_method, overwritten, visibility)
9
- if old_method.name != new_method.name
10
- raise "Method names must match. old=#{old_method.name} new=#{new_method.name}"
11
- end
12
- @mod = mod
13
- @old_method = old_method
14
- @new_method = new_method
15
- @overwritten = overwritten
16
- @name = old_method.name
17
- @visibility = visibility
18
- @restored = false
19
- end
20
-
21
- def restore
22
- # The check below would also catch this, but this makes the failure mode much clearer
23
- if @restored
24
- raise "Method '#{@name}' on '#{@mod}' was already restored"
25
- end
26
-
27
- if @mod.instance_method(@name) != @new_method
28
- raise "Trying to restore #{@mod}##{@name} but the method has changed since the call to replace_method"
29
- end
30
-
31
- @restored = true
32
-
33
- if @overwritten
34
- # The original method was overwritten. Overwrite again to restore it.
35
- T::Configuration.without_ruby_warnings do
36
- @mod.send(:define_method, @old_method.name, @old_method)
37
- end
38
- else
39
- # The original method was in an ancestor. Restore it by removing the overriding method.
40
- @mod.send(:remove_method, @old_method.name)
41
- end
42
-
43
- # Restore the visibility. Note that we need to do this even when we call remove_method
44
- # above, because the module may have set custom visibility for a method it inherited.
45
- @mod.send(@visibility, @old_method.name)
46
-
47
- nil
48
- end
49
-
50
- def bind(obj)
51
- @old_method.bind(obj)
52
- end
53
-
54
- def to_s
55
- @old_method.to_s
56
- end
57
- end
58
-
59
12
  # `name` must be an instance method (for class methods, pass in mod.singleton_class)
60
- private_class_method def self.visibility_method_name(mod, name)
13
+ def self.visibility_method_name(mod, name)
61
14
  if mod.public_method_defined?(name)
62
15
  :public
63
16
  elsif mod.protected_method_defined?(name)
@@ -65,7 +18,10 @@ module T::Private::ClassUtils
65
18
  elsif mod.private_method_defined?(name)
66
19
  :private
67
20
  else
68
- mod.method(name) # Raises
21
+ # Raises a NameError formatted like the Ruby VM would (the exact text formatting
22
+ # of these errors changed across Ruby VM versions, in ways that would sometimes
23
+ # cause tests to fail if they were dependent on hard coding errors).
24
+ mod.method(name)
69
25
  end
70
26
  end
71
27
 
@@ -90,15 +46,18 @@ module T::Private::ClassUtils
90
46
  end
91
47
  end
92
48
 
93
- # Replaces a method, either by overwriting it (if it is defined directly on `mod`) or by
94
- # overriding it (if it is defined by one of mod's ancestors). If `original_only` is
95
- # false, returns a ReplacedMethod instance on which you can call `bind(...).call(...)`
96
- # to call the original method, or `restore` to restore the original method (by
97
- # overwriting or removing the override).
49
+ # Replaces a method, either by overwriting it (if it is defined directly on
50
+ # `mod`) or by overriding it (if it is defined by one of mod's ancestors).
51
+ #
52
+ # Takes the `original_method` as a parameter, so it does not return anything.
53
+ #
54
+ # Can also avoid `T.let` pinning errors by letting the caller pre-compute the
55
+ # `original_method`, so it knows that it will always be defined (because it
56
+ # doesn't know that the block will always run once)
98
57
  #
99
- # If `original_only` is true, return the `UnboundMethod` representing the original method.
100
- def self.replace_method(mod, name, original_only=false, &blk)
101
- original_method = mod.instance_method(name)
58
+ # Does not share code with `replace_method_with_handle`, for performance (do
59
+ # not want to increase the call stack, as this is a very sensitive code path).
60
+ def self.replace_method(original_method, mod, name, &blk)
102
61
  original_visibility = visibility_method_name(mod, name)
103
62
  original_owner = original_method.owner
104
63
 
@@ -117,18 +76,12 @@ module T::Private::ClassUtils
117
76
  end
118
77
  end
119
78
 
120
- overwritten = original_owner == mod
121
79
  T::Configuration.without_ruby_warnings do
122
80
  T::Private::DeclState.current.without_on_method_added do
123
81
  def_with_visibility(mod, name, original_visibility, &blk)
124
82
  end
125
83
  end
126
84
 
127
- if original_only
128
- original_method
129
- else
130
- new_method = mod.instance_method(name)
131
- ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility)
132
- end
85
+ nil
133
86
  end
134
87
  end
@@ -34,7 +34,13 @@ module T::Private::Methods
34
34
  ARG_NOT_PROVIDED = Object.new
35
35
  PROC_TYPE = Object.new
36
36
 
37
- DeclarationBlock = Struct.new(:mod, :loc, :blk, :final, :raw)
37
+ # blk_or_decl:
38
+ # - It's a `Proc` if we haven't forced the thunk yet.
39
+ # - It's a `Declaration` if we have, but we haven't finished building the sig
40
+ # (This can matter for circular load-time behavior, where a method is
41
+ # called while its Signature is being built)
42
+ # - It's `nil` if we've finished building the sig
43
+ DeclarationBlock = Struct.new(:mod, :loc, :blk_or_decl, :final, :raw)
38
44
 
39
45
  def self.declare_sig(mod, loc, arg, &blk)
40
46
  T::Private::DeclState.current.active_declaration = _declare_sig_internal(mod, loc, arg, &blk)
@@ -236,7 +242,7 @@ module T::Private::Methods
236
242
  # (or unwrap back to the original method).
237
243
  key = method_owner_and_name_to_key(mod, method_name)
238
244
  unless current_declaration.raw
239
- T::Private::ClassUtils.replace_method(mod, method_name, true) do |*args, &blk|
245
+ T::Private::ClassUtils.replace_method(original_method, mod, method_name) do |*args, &blk|
240
246
  method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key)
241
247
  method_sig ||= T::Private::Methods._handle_missing_method_signature(
242
248
  self,
@@ -321,6 +327,7 @@ module T::Private::Methods
321
327
  nil
322
328
  end
323
329
 
330
+ # Release location information sooner
324
331
  declaration_block.loc = nil
325
332
 
326
333
  signature =
@@ -331,15 +338,28 @@ module T::Private::Methods
331
338
  end
332
339
 
333
340
  unwrap_method(signature.method.owner, signature, original_method)
341
+
342
+ # Drop this declaration. Only drop it after we've actually wrapped the
343
+ # method and recorded the signature, because that might raise an exception,
344
+ # leaving the declaration in a weird state if the program rescues that
345
+ # exception and continues.
346
+ declaration_block.blk_or_decl = nil
347
+
334
348
  signature
335
349
  end
336
350
 
337
351
  def self.run_builder(declaration_block)
352
+ blk_or_decl = declaration_block.blk_or_decl
353
+ return blk_or_decl if blk_or_decl.is_a?(Declaration)
354
+ if blk_or_decl.nil?
355
+ raise "DeclarationBlock for #{declaration_block.mod} at #{declaration_block.loc} should have already been unwrapped"
356
+ end
357
+
338
358
  builder = DeclBuilder.new(declaration_block.mod, declaration_block.raw)
339
- builder
340
- .instance_exec(&declaration_block.blk)
341
- .finalize!
342
- .decl
359
+ decl = builder.instance_exec(&blk_or_decl).finalize!.decl
360
+ # Record that we've already run `blk` once and constructed a `Declaration`
361
+ declaration_block.blk_or_decl = decl
362
+ decl
343
363
  end
344
364
 
345
365
  def self.build_sig(hook_mod, method_name, original_method, current_declaration)
@@ -400,7 +420,7 @@ module T::Private::Methods
400
420
  @signatures_by_method[key]
401
421
  end
402
422
 
403
- def self.unwrap_method(mod, signature, original_method)
423
+ private_class_method def self.unwrap_method(mod, signature, original_method)
404
424
  maybe_wrapped_method = CallValidation.wrap_method_if_needed(mod, signature, original_method)
405
425
  @signatures_by_method[method_to_key(maybe_wrapped_method)] = signature
406
426
  end
@@ -439,12 +459,6 @@ module T::Private::Methods
439
459
  method_owner_and_name_to_key(method.owner, method.name)
440
460
  end
441
461
 
442
- private_class_method def self.key_to_method(key)
443
- id, name = key.split("#")
444
- obj = ObjectSpace._id2ref(id.to_i)
445
- obj.instance_method(name)
446
- end
447
-
448
462
  private_class_method def self.run_sig_block_for_key(key, force_type_init: false)
449
463
  blk = @sig_wrappers[key]
450
464
  if !blk
@@ -453,7 +467,7 @@ module T::Private::Methods
453
467
  # We already ran the sig block, perhaps in another thread.
454
468
  return sig
455
469
  else
456
- raise "No `sig` wrapper for #{key_to_method(key)}"
470
+ raise "No `sig` wrapper for #{key}. This is likely a bug in sorbet-runtime. If you can reproduce, please report an issue."
457
471
  end
458
472
  end
459
473
 
@@ -464,7 +478,7 @@ module T::Private::Methods
464
478
  raise
465
479
  end
466
480
  if @sigs_that_raised[key]
467
- raise "A previous invocation of #{key_to_method(key)} raised, and the current one succeeded. Please don't do that."
481
+ raise "A previous invocation of #{sig.method_desc} raised, and the current one succeeded. Please don't do that."
468
482
  end
469
483
 
470
484
  @sig_wrappers.delete(key)
@@ -527,15 +541,21 @@ module T::Private::Methods
527
541
  end
528
542
  @old_hooks = nil
529
543
  else
530
- old_included = T::Private::ClassUtils.replace_method(Module, :included, true) do |arg|
544
+ # Grab the original methods before replacing them, so that each block
545
+ # closure can reference a variable that is already assigned.
546
+ # (Do this directly, to avoid pinning errors)
547
+ old_included = Module.instance_method(:included)
548
+ T::Private::ClassUtils.replace_method(old_included, Module, :included) do |arg|
531
549
  old_included.bind_call(self, arg)
532
550
  ::T::Private::Methods._hook_impl(arg, false, self)
533
551
  end
534
- old_extended = T::Private::ClassUtils.replace_method(Module, :extended, true) do |arg|
552
+ old_extended = Module.instance_method(:extended)
553
+ T::Private::ClassUtils.replace_method(old_extended, Module, :extended) do |arg|
535
554
  old_extended.bind_call(self, arg)
536
555
  ::T::Private::Methods._hook_impl(arg, true, self)
537
556
  end
538
- old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited, true) do |arg|
557
+ old_inherited = Class.instance_method(:inherited)
558
+ T::Private::ClassUtils.replace_method(old_inherited, Class, :inherited) do |arg|
539
559
  old_inherited.bind_call(self, arg)
540
560
  ::T::Private::Methods._hook_impl(arg, false, self)
541
561
  end
@@ -588,22 +608,6 @@ module T::Private::Methods
588
608
  end
589
609
  mod.extend(SingletonMethodHooks)
590
610
  end
591
-
592
- # `name` must be an instance method (for class methods, pass in mod.singleton_class)
593
- def self.visibility_method_name(mod, name)
594
- if mod.public_method_defined?(name)
595
- :public
596
- elsif mod.protected_method_defined?(name)
597
- :protected
598
- elsif mod.private_method_defined?(name)
599
- :private
600
- else
601
- # Raises a NameError formatted like the Ruby VM would (the exact text formatting
602
- # of these errors changed across Ruby VM versions, in ways that would sometimes
603
- # cause tests to fail if they were dependent on hard coding errors).
604
- mod.method(name)
605
- end
606
- end
607
611
  end
608
612
 
609
613
  # This has to be here, and can't be nested inside `T::Private::Methods`,
@@ -5,6 +5,10 @@ module T::Private::Methods::CallValidation
5
5
  CallValidation = T::Private::Methods::CallValidation
6
6
  Modes = T::Private::Methods::Modes
7
7
 
8
+ KERNEL_TO_S = Kernel.instance_method(:to_s)
9
+ MODULE_TO_S = Module.instance_method(:to_s)
10
+ private_constant(:KERNEL_TO_S, :MODULE_TO_S)
11
+
8
12
  # Wraps a method with a layer of validation for the given type signature.
9
13
  # This wrapper is meant to be fast, and is applied by a previous wrapper,
10
14
  # which was placed by `_on_method_added`.
@@ -12,7 +16,7 @@ module T::Private::Methods::CallValidation
12
16
  # @param method_sig [T::Private::Methods::Signature]
13
17
  # @return [UnboundMethod] the new wrapper method (or the original one if we didn't wrap it)
14
18
  def self.wrap_method_if_needed(mod, method_sig, original_method)
15
- original_visibility = T::Private::Methods.visibility_method_name(mod, method_sig.method_name)
19
+ original_visibility = T::Private::ClassUtils.visibility_method_name(mod, method_sig.method_name)
16
20
  if method_sig.mode == T::Private::Methods::Modes.abstract
17
21
  create_abstract_wrapper(mod, method_sig, original_method, original_visibility)
18
22
  # Do nothing in this case; this method was not wrapped in _on_method_added.
@@ -68,24 +72,32 @@ module T::Private::Methods::CallValidation
68
72
  end
69
73
 
70
74
  def self.create_validator_method(mod, original_method, method_sig, original_visibility)
71
- has_fixed_arity = method_sig.kwarg_types.empty? && !method_sig.has_rest && !method_sig.has_keyrest &&
75
+ has_fixed_arity = method_sig.kwarg_types.empty? && method_sig.rest_type.nil? && method_sig.keyrest_type.nil? &&
72
76
  original_method.parameters.all? { |(kind, _name)| kind == :req || kind == :block }
73
- can_skip_block_type = method_sig.block_type.nil? || method_sig.block_type.valid?(nil)
77
+
78
+ # nil implies block_type.nil?
79
+ # true implies !block_type.nil? and block_type.valid?(nil)
80
+ # false implies !block_type.nil? and !block_type.valid?(nil)
81
+ # This formulation avoids a type error without introducing extra method calls or local vars
82
+ can_skip_block_type = method_sig.block_type&.valid?(nil) != false
83
+
74
84
  ok_for_fast_path = has_fixed_arity && can_skip_block_type && !method_sig.bind && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
75
85
 
76
86
  all_args_are_simple = ok_for_fast_path && method_sig.arg_types.all? { |_name, type| type.is_a?(T::Types::Simple) }
77
- simple_method = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple)
78
- simple_procedure = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void)
87
+
88
+ effective_return_type = method_sig.effective_return_type
89
+ simple_method = all_args_are_simple && effective_return_type.is_a?(T::Types::Simple)
90
+ simple_procedure = all_args_are_simple && effective_return_type.is_a?(T::Private::Types::Void)
79
91
 
80
92
  # All the types for which valid? unconditionally returns `true`
81
93
  return_is_ignorable =
82
- method_sig.return_type.equal?(T::Types::Untyped::Private::INSTANCE) ||
83
- method_sig.return_type.equal?(T::Types::Anything::Private::INSTANCE) ||
84
- method_sig.return_type.equal?(T::Types::AttachedClassType::Private::INSTANCE) ||
85
- method_sig.return_type.equal?(T::Types::SelfType::Private::INSTANCE) ||
86
- method_sig.return_type.is_a?(T::Types::TypeParameter) ||
87
- method_sig.return_type.is_a?(T::Types::TypeVariable) ||
88
- (method_sig.return_type.is_a?(T::Types::Simple) && method_sig.return_type.raw_type.equal?(BasicObject))
94
+ effective_return_type.equal?(T::Types::Untyped::Private::INSTANCE) ||
95
+ effective_return_type.equal?(T::Types::Anything::Private::INSTANCE) ||
96
+ effective_return_type.equal?(T::Types::AttachedClassType::Private::INSTANCE) ||
97
+ effective_return_type.equal?(T::Types::SelfType::Private::INSTANCE) ||
98
+ effective_return_type.is_a?(T::Types::TypeParameter) ||
99
+ effective_return_type.is_a?(T::Types::TypeVariable) ||
100
+ (effective_return_type.is_a?(T::Types::Simple) && effective_return_type.raw_type.equal?(BasicObject))
89
101
 
90
102
  returns_anything_method = all_args_are_simple && return_is_ignorable
91
103
 
@@ -97,7 +109,7 @@ module T::Private::Methods::CallValidation
97
109
  create_validator_method_skip_return_fast(mod, original_method, method_sig, original_visibility)
98
110
  elsif simple_procedure
99
111
  create_validator_procedure_fast(mod, original_method, method_sig, original_visibility)
100
- elsif ok_for_fast_path && method_sig.return_type.is_a?(T::Private::Types::Void)
112
+ elsif ok_for_fast_path && effective_return_type.is_a?(T::Private::Types::Void)
101
113
  create_validator_procedure_medium(mod, original_method, method_sig, original_visibility)
102
114
  elsif ok_for_fast_path && return_is_ignorable
103
115
  create_validator_method_skip_return_medium(mod, original_method, method_sig, original_visibility)
@@ -180,17 +192,17 @@ module T::Private::Methods::CallValidation
180
192
 
181
193
  # The only type that is allowed to change the return value is `.void`.
182
194
  # It ignores what you returned and changes it to be a private singleton.
183
- if method_sig.return_type.is_a?(T::Private::Types::Void)
195
+ if method_sig.effective_return_type.is_a?(T::Private::Types::Void)
184
196
  T::Private::Types::Void::VOID
185
197
  else
186
- message = method_sig.return_type.error_message_for_obj(return_value)
198
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
187
199
  if message
188
200
  CallValidation.report_error(
189
201
  method_sig,
190
202
  message,
191
203
  'Return value',
192
204
  nil,
193
- method_sig.return_type,
205
+ method_sig.effective_return_type,
194
206
  return_value,
195
207
  )
196
208
  end
@@ -283,17 +295,17 @@ module T::Private::Methods::CallValidation
283
295
 
284
296
  # The only type that is allowed to change the return value is `.void`.
285
297
  # It ignores what you returned and changes it to be a private singleton.
286
- if method_sig.return_type.is_a?(T::Private::Types::Void)
298
+ if method_sig.effective_return_type.is_a?(T::Private::Types::Void)
287
299
  T::Private::Types::Void::VOID
288
300
  else
289
- message = method_sig.return_type.error_message_for_obj(return_value)
301
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
290
302
  if message
291
303
  CallValidation.report_error(
292
304
  method_sig,
293
305
  message,
294
306
  'Return value',
295
307
  nil,
296
- method_sig.return_type,
308
+ method_sig.effective_return_type,
297
309
  return_value,
298
310
  )
299
311
  end
@@ -301,6 +313,16 @@ module T::Private::Methods::CallValidation
301
313
  end
302
314
  end
303
315
 
316
+ # Get the name of a method owner via its `.to_s`, but fallback if its implementation raises or returns `nil`.
317
+ private_class_method def self.safe_method_owner_to_s(method_owner)
318
+ case method_owner
319
+ when Module # methods are usually owned by a Class or Module...
320
+ MODULE_TO_S.bind_call(method_owner)
321
+ else # ... but could be a singleton method on any kind of Object.
322
+ KERNEL_TO_S.bind_call(method_owner)
323
+ end
324
+ end
325
+
304
326
  def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0)
305
327
  caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0]
306
328
  method = method_sig.method
@@ -310,9 +332,9 @@ module T::Private::Methods::CallValidation
310
332
  pretty_method_name =
311
333
  if owner.singleton_class? && owner.respond_to?(:attached_object)
312
334
  # attached_object is new in Ruby 3.2
313
- "#{owner.attached_object}.#{method.name}"
335
+ "#{safe_method_owner_to_s(owner.attached_object)}.#{method.name}"
314
336
  else
315
- "#{owner}##{method.name}"
337
+ "#{safe_method_owner_to_s(owner)}##{method.name}"
316
338
  end
317
339
 
318
340
  pretty_message = "#{kind}#{name ? " '#{name}'" : ''}: #{error_message}\n" \
@@ -7,28 +7,28 @@
7
7
 
8
8
  module T::Private::Methods::CallValidation
9
9
  def self.create_validator_method_fast(mod, original_method, method_sig, original_visibility)
10
- if method_sig.return_type.is_a?(T::Private::Types::Void)
10
+ if method_sig.effective_return_type.is_a?(T::Private::Types::Void)
11
11
  raise 'Should have used create_validator_procedure_fast'
12
12
  end
13
13
  # trampoline to reduce stack frame size
14
14
  arg_types = method_sig.arg_types
15
15
  case arg_types.length
16
16
  when 0
17
- create_validator_method_fast0(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type)
17
+ create_validator_method_fast0(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type.raw_type)
18
18
  when 1
19
- create_validator_method_fast1(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
19
+ create_validator_method_fast1(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type.raw_type,
20
20
  arg_types[0][1].raw_type)
21
21
  when 2
22
- create_validator_method_fast2(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
22
+ create_validator_method_fast2(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type.raw_type,
23
23
  arg_types[0][1].raw_type,
24
24
  arg_types[1][1].raw_type)
25
25
  when 3
26
- create_validator_method_fast3(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
26
+ create_validator_method_fast3(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type.raw_type,
27
27
  arg_types[0][1].raw_type,
28
28
  arg_types[1][1].raw_type,
29
29
  arg_types[2][1].raw_type)
30
30
  when 4
31
- create_validator_method_fast4(mod, original_method, method_sig, original_visibility, method_sig.return_type.raw_type,
31
+ create_validator_method_fast4(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type.raw_type,
32
32
  arg_types[0][1].raw_type,
33
33
  arg_types[1][1].raw_type,
34
34
  arg_types[2][1].raw_type,
@@ -58,14 +58,14 @@ module T::Private::Methods::CallValidation
58
58
 
59
59
  return_value = original_method.bind_call(self, &blk)
60
60
  unless return_value.is_a?(return_type)
61
- message = method_sig.return_type.error_message_for_obj(return_value)
61
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
62
62
  if message
63
63
  CallValidation.report_error(
64
64
  method_sig,
65
65
  message,
66
66
  'Return value',
67
67
  nil,
68
- method_sig.return_type,
68
+ method_sig.effective_return_type,
69
69
  return_value,
70
70
  caller_offset: -1
71
71
  )
@@ -107,14 +107,14 @@ module T::Private::Methods::CallValidation
107
107
 
108
108
  return_value = original_method.bind_call(self, arg0, &blk)
109
109
  unless return_value.is_a?(return_type)
110
- message = method_sig.return_type.error_message_for_obj(return_value)
110
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
111
111
  if message
112
112
  CallValidation.report_error(
113
113
  method_sig,
114
114
  message,
115
115
  'Return value',
116
116
  nil,
117
- method_sig.return_type,
117
+ method_sig.effective_return_type,
118
118
  return_value,
119
119
  caller_offset: -1
120
120
  )
@@ -168,14 +168,14 @@ module T::Private::Methods::CallValidation
168
168
 
169
169
  return_value = original_method.bind_call(self, arg0, arg1, &blk)
170
170
  unless return_value.is_a?(return_type)
171
- message = method_sig.return_type.error_message_for_obj(return_value)
171
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
172
172
  if message
173
173
  CallValidation.report_error(
174
174
  method_sig,
175
175
  message,
176
176
  'Return value',
177
177
  nil,
178
- method_sig.return_type,
178
+ method_sig.effective_return_type,
179
179
  return_value,
180
180
  caller_offset: -1
181
181
  )
@@ -241,14 +241,14 @@ module T::Private::Methods::CallValidation
241
241
 
242
242
  return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk)
243
243
  unless return_value.is_a?(return_type)
244
- message = method_sig.return_type.error_message_for_obj(return_value)
244
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
245
245
  if message
246
246
  CallValidation.report_error(
247
247
  method_sig,
248
248
  message,
249
249
  'Return value',
250
250
  nil,
251
- method_sig.return_type,
251
+ method_sig.effective_return_type,
252
252
  return_value,
253
253
  caller_offset: -1
254
254
  )
@@ -326,14 +326,14 @@ module T::Private::Methods::CallValidation
326
326
 
327
327
  return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk)
328
328
  unless return_value.is_a?(return_type)
329
- message = method_sig.return_type.error_message_for_obj(return_value)
329
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
330
330
  if message
331
331
  CallValidation.report_error(
332
332
  method_sig,
333
333
  message,
334
334
  'Return value',
335
335
  nil,
336
- method_sig.return_type,
336
+ method_sig.effective_return_type,
337
337
  return_value,
338
338
  caller_offset: -1
339
339
  )
@@ -867,28 +867,28 @@ module T::Private::Methods::CallValidation
867
867
  end
868
868
 
869
869
  def self.create_validator_method_medium(mod, original_method, method_sig, original_visibility)
870
- if method_sig.return_type.is_a?(T::Private::Types::Void)
870
+ if method_sig.effective_return_type.is_a?(T::Private::Types::Void)
871
871
  raise 'Should have used create_validator_procedure_medium'
872
872
  end
873
873
  # trampoline to reduce stack frame size
874
874
  arg_types = method_sig.arg_types
875
875
  case arg_types.length
876
876
  when 0
877
- create_validator_method_medium0(mod, original_method, method_sig, original_visibility, method_sig.return_type)
877
+ create_validator_method_medium0(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type)
878
878
  when 1
879
- create_validator_method_medium1(mod, original_method, method_sig, original_visibility, method_sig.return_type,
879
+ create_validator_method_medium1(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type,
880
880
  arg_types[0][1])
881
881
  when 2
882
- create_validator_method_medium2(mod, original_method, method_sig, original_visibility, method_sig.return_type,
882
+ create_validator_method_medium2(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type,
883
883
  arg_types[0][1],
884
884
  arg_types[1][1])
885
885
  when 3
886
- create_validator_method_medium3(mod, original_method, method_sig, original_visibility, method_sig.return_type,
886
+ create_validator_method_medium3(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type,
887
887
  arg_types[0][1],
888
888
  arg_types[1][1],
889
889
  arg_types[2][1])
890
890
  when 4
891
- create_validator_method_medium4(mod, original_method, method_sig, original_visibility, method_sig.return_type,
891
+ create_validator_method_medium4(mod, original_method, method_sig, original_visibility, method_sig.effective_return_type,
892
892
  arg_types[0][1],
893
893
  arg_types[1][1],
894
894
  arg_types[2][1],
@@ -918,14 +918,14 @@ module T::Private::Methods::CallValidation
918
918
 
919
919
  return_value = original_method.bind_call(self, &blk)
920
920
  unless return_type.valid?(return_value)
921
- message = method_sig.return_type.error_message_for_obj(return_value)
921
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
922
922
  if message
923
923
  CallValidation.report_error(
924
924
  method_sig,
925
925
  message,
926
926
  'Return value',
927
927
  nil,
928
- method_sig.return_type,
928
+ method_sig.effective_return_type,
929
929
  return_value,
930
930
  caller_offset: -1
931
931
  )
@@ -967,14 +967,14 @@ module T::Private::Methods::CallValidation
967
967
 
968
968
  return_value = original_method.bind_call(self, arg0, &blk)
969
969
  unless return_type.valid?(return_value)
970
- message = method_sig.return_type.error_message_for_obj(return_value)
970
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
971
971
  if message
972
972
  CallValidation.report_error(
973
973
  method_sig,
974
974
  message,
975
975
  'Return value',
976
976
  nil,
977
- method_sig.return_type,
977
+ method_sig.effective_return_type,
978
978
  return_value,
979
979
  caller_offset: -1
980
980
  )
@@ -1028,14 +1028,14 @@ module T::Private::Methods::CallValidation
1028
1028
 
1029
1029
  return_value = original_method.bind_call(self, arg0, arg1, &blk)
1030
1030
  unless return_type.valid?(return_value)
1031
- message = method_sig.return_type.error_message_for_obj(return_value)
1031
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
1032
1032
  if message
1033
1033
  CallValidation.report_error(
1034
1034
  method_sig,
1035
1035
  message,
1036
1036
  'Return value',
1037
1037
  nil,
1038
- method_sig.return_type,
1038
+ method_sig.effective_return_type,
1039
1039
  return_value,
1040
1040
  caller_offset: -1
1041
1041
  )
@@ -1101,14 +1101,14 @@ module T::Private::Methods::CallValidation
1101
1101
 
1102
1102
  return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk)
1103
1103
  unless return_type.valid?(return_value)
1104
- message = method_sig.return_type.error_message_for_obj(return_value)
1104
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
1105
1105
  if message
1106
1106
  CallValidation.report_error(
1107
1107
  method_sig,
1108
1108
  message,
1109
1109
  'Return value',
1110
1110
  nil,
1111
- method_sig.return_type,
1111
+ method_sig.effective_return_type,
1112
1112
  return_value,
1113
1113
  caller_offset: -1
1114
1114
  )
@@ -1186,14 +1186,14 @@ module T::Private::Methods::CallValidation
1186
1186
 
1187
1187
  return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk)
1188
1188
  unless return_type.valid?(return_value)
1189
- message = method_sig.return_type.error_message_for_obj(return_value)
1189
+ message = method_sig.effective_return_type.error_message_for_obj(return_value)
1190
1190
  if message
1191
1191
  CallValidation.report_error(
1192
1192
  method_sig,
1193
1193
  message,
1194
1194
  'Return value',
1195
1195
  nil,
1196
- method_sig.return_type,
1196
+ method_sig.effective_return_type,
1197
1197
  return_value,
1198
1198
  caller_offset: -1
1199
1199
  )
@@ -22,10 +22,10 @@ module T::Private::Methods
22
22
  ARG_NOT_PROVIDED, # returns
23
23
  ARG_NOT_PROVIDED, # bind
24
24
  Modes.standard, # mode
25
- ARG_NOT_PROVIDED, # checked
25
+ nil, # checked
26
26
  false, # finalized
27
27
  ARG_NOT_PROVIDED, # on_failure
28
- nil, # override_allow_incompatible
28
+ false, # override_allow_incompatible
29
29
  ARG_NOT_PROVIDED, # type_parameters
30
30
  raw
31
31
  )
@@ -98,10 +98,10 @@ module T::Private::Methods
98
98
  def checked(level)
99
99
  check_live!
100
100
 
101
- if !decl.checked.equal?(ARG_NOT_PROVIDED)
101
+ if !decl.checked.nil?
102
102
  raise BuilderError.new("You can't call .checked multiple times in a signature.")
103
103
  end
104
- if level == :never && !decl.on_failure.equal?(ARG_NOT_PROVIDED)
104
+ if :never == level && !decl.on_failure.equal?(ARG_NOT_PROVIDED)
105
105
  raise BuilderError.new("You can't use .checked(:#{level}) with .on_failure because .on_failure will have no effect.")
106
106
  end
107
107
  if !T::Private::RuntimeLevels::LEVELS.include?(level)
@@ -119,8 +119,13 @@ module T::Private::Methods
119
119
  if !decl.on_failure.equal?(ARG_NOT_PROVIDED)
120
120
  raise BuilderError.new("You can't call .on_failure multiple times in a signature.")
121
121
  end
122
- if decl.checked == :never
123
- raise BuilderError.new("You can't use .on_failure with .checked(:#{decl.checked}) because .on_failure will have no effect.")
122
+ effective_checked = decl.checked.nil? ? T::Private::RuntimeLevels.default_checked_level : decl.checked
123
+ if effective_checked == :never
124
+ if decl.checked.nil?
125
+ raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.")
126
+ else
127
+ raise BuilderError.new("You can't use .on_failure with .checked(:#{effective_checked}) because .on_failure will have no effect.")
128
+ end
124
129
  end
125
130
 
126
131
  decl.on_failure = args
@@ -225,13 +230,6 @@ module T::Private::Methods
225
230
  if decl.bind.equal?(ARG_NOT_PROVIDED)
226
231
  decl.bind = nil
227
232
  end
228
- if decl.checked.equal?(ARG_NOT_PROVIDED)
229
- default_checked_level = T::Private::RuntimeLevels.default_checked_level
230
- if default_checked_level == :never && !decl.on_failure.equal?(ARG_NOT_PROVIDED)
231
- raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.")
232
- end
233
- decl.checked = default_checked_level
234
- end
235
233
  if decl.on_failure.equal?(ARG_NOT_PROVIDED)
236
234
  decl.on_failure = nil
237
235
  end
@@ -3,8 +3,8 @@
3
3
 
4
4
  class T::Private::Methods::Signature
5
5
  attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name,
6
- :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind,
7
- :return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest,
6
+ :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind, :effective_return_type,
7
+ :return_type, :mode, :req_arg_count, :req_kwarg_names,
8
8
  :check_level, :parameters, :on_failure, :override_allow_incompatible,
9
9
  :defined_raw
10
10
 
@@ -37,6 +37,7 @@ class T::Private::Methods::Signature
37
37
  end
38
38
 
39
39
  def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false)
40
+ check_level = check_level.nil? ? T::Private::RuntimeLevels.default_checked_level : check_level
40
41
  @method = method
41
42
  @method_name = method_name
42
43
  @block_type = nil
@@ -46,11 +47,14 @@ class T::Private::Methods::Signature
46
47
  @keyrest_type = nil
47
48
  @keyrest_name = nil
48
49
  @return_type = T::Utils.coerce(raw_return_type)
50
+ @effective_return_type = if check_level == :tests && @return_type.is_a?(T::Private::Types::Void)
51
+ T::Types::Anything::Private::INSTANCE
52
+ else
53
+ @return_type
54
+ end
49
55
  @bind = bind ? T::Utils.coerce(bind) : bind
50
56
  @mode = mode
51
57
  @check_level = check_level
52
- @has_rest = false
53
- @has_keyrest = false
54
58
  @parameters = parameters
55
59
  @on_failure = on_failure
56
60
  @override_allow_incompatible = override_allow_incompatible
@@ -134,11 +138,9 @@ class T::Private::Methods::Signature
134
138
  @block_name = param_name
135
139
  @block_type = type
136
140
  when :rest
137
- @has_rest = true
138
141
  @rest_name = param_name
139
142
  @rest_type = type
140
143
  when :keyrest
141
- @has_keyrest = true
142
144
  @keyrest_name = param_name
143
145
  @keyrest_type = type
144
146
  else
@@ -175,10 +177,6 @@ class T::Private::Methods::Signature
175
177
  @method.owner
176
178
  end
177
179
 
178
- def dsl_method
179
- "#{@mode}_method"
180
- end
181
-
182
180
  # @return [Hash] a mapping like `{arg_name: [val, type], ...}`, for only those args actually present.
183
181
  def each_args_value_type(args)
184
182
  # Manually split out args and kwargs based on ruby's behavior. Do not try to implement this by
@@ -189,14 +187,14 @@ class T::Private::Methods::Signature
189
187
  # causes forwarding **kwargs to do the wrong thing: see https://bugs.ruby-lang.org/issues/10708
190
188
  # and https://bugs.ruby-lang.org/issues/11860.
191
189
  args_length = args.length
192
- if (args_length > @req_arg_count) && (!@kwarg_types.empty? || @has_keyrest) && args[-1].is_a?(Hash)
193
- kwargs = args[-1]
190
+ if (args_length > @req_arg_count) && (!@kwarg_types.empty? || !@keyrest_type.nil?) && (last_arg = args[-1]).is_a?(Hash)
191
+ kwargs = last_arg
194
192
  args_length -= 1
195
193
  else
196
194
  kwargs = EMPTY_HASH
197
195
  end
198
196
 
199
- if !@has_rest && ((args_length < @req_arg_count) || (args_length > @arg_types.length))
197
+ if @rest_type.nil? && ((args_length < @req_arg_count) || (args_length > @arg_types.length))
200
198
  expected_str = @req_arg_count.to_s
201
199
  if @arg_types.length != @req_arg_count
202
200
  expected_str += "..#{@arg_types.length}"
@@ -210,11 +208,12 @@ class T::Private::Methods::Signature
210
208
  # Process given pre-rest args. When there are no rest args,
211
209
  # this is just the given number of args.
212
210
  while it < args_length && it < @arg_types.length
213
- yield @arg_types[it][0], args[it], @arg_types[it][1]
211
+ arg_type = @arg_types.fetch(it)
212
+ yield arg_type[0], args[it], arg_type[1]
214
213
  it += 1
215
214
  end
216
215
 
217
- if @has_rest
216
+ if !@rest_type.nil?
218
217
  rest_count = args_length - @arg_types.length
219
218
  rest_count = 0 if rest_count.negative?
220
219
 
@@ -227,7 +226,7 @@ class T::Private::Methods::Signature
227
226
 
228
227
  kwargs.each do |name, val|
229
228
  type = @kwarg_types[name]
230
- if !type && @has_keyrest
229
+ if !type && !@keyrest_type.nil?
231
230
  type = @keyrest_type
232
231
  end
233
232
 
@@ -236,12 +235,12 @@ class T::Private::Methods::Signature
236
235
  end
237
236
 
238
237
  def method_desc
239
- loc = if @method.source_location
240
- @method.source_location.join(':')
238
+ loc = if (source_loc = @method.source_location)
239
+ source_loc.join(':')
241
240
  else
242
241
  "<unknown location>"
243
242
  end
244
- "#{@method} at #{loc}"
243
+ "#{@method.owner}##{@method_name} at #{loc}"
245
244
  end
246
245
 
247
246
  def force_type_init
@@ -126,12 +126,12 @@ module T::Private::Methods::SignatureValidation
126
126
  # Peaceful
127
127
  elsif super_signature.mode == Modes.abstract
128
128
  raise "You must use `.override` when overriding the abstract method `#{signature.method_name}`.\n" \
129
- " Abstract definition: #{method_loc_str(super_signature.method)}\n" \
130
- " Implementation definition: #{method_loc_str(signature.method)}\n"
129
+ " Abstract definition: #{super_signature.method_desc}\n" \
130
+ " Implementation definition: #{signature.method_desc}\n"
131
131
  elsif super_signature.mode != Modes.untyped
132
132
  raise "You must use `.override` when overriding the existing method `#{signature.method_name}`.\n" \
133
- " Parent definition: #{method_loc_str(super_signature.method)}\n" \
134
- " Child definition: #{method_loc_str(signature.method)}\n"
133
+ " Parent definition: #{super_signature.method_desc}\n" \
134
+ " Child definition: #{signature.method_desc}\n"
135
135
  end
136
136
  else
137
137
  raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues"
@@ -153,7 +153,7 @@ module T::Private::Methods::SignatureValidation
153
153
  else
154
154
  raise "You marked `#{signature.method_name}` as #{pretty_mode(signature)}, but that method doesn't already exist in this class/module to be overridden.\n" \
155
155
  " Either check for typos and for missing includes or super classes to make the parent method shows up\n" \
156
- " ... or remove #{pretty_mode(signature)} here: #{method_loc_str(signature.method)}\n"
156
+ " ... or remove #{pretty_mode(signature)} here: #{signature.method_desc}\n"
157
157
  end
158
158
  when Modes.standard, *Modes::NON_OVERRIDE_MODES
159
159
  # Peaceful
@@ -182,13 +182,13 @@ module T::Private::Methods::SignatureValidation
182
182
  method_name = signature.method_name
183
183
  mode_verb = super_signature.mode == Modes.abstract ? 'implements' : 'overrides'
184
184
 
185
- if !signature.has_rest && signature.arg_count < super_signature.arg_count
185
+ if signature.rest_type.nil? && signature.arg_count < super_signature.arg_count
186
186
  raise "Your definition of `#{method_name}` must accept at least #{super_signature.arg_count} " \
187
187
  "positional arguments to be compatible with the method it #{mode_verb}: " \
188
188
  "#{base_override_loc_str(signature, super_signature)}"
189
189
  end
190
190
 
191
- if !signature.has_rest && super_signature.has_rest
191
+ if signature.rest_type.nil? && !super_signature.rest_type.nil?
192
192
  raise "Your definition of `#{method_name}` must have `*#{super_signature.rest_name}` " \
193
193
  "to be compatible with the method it #{mode_verb}: " \
194
194
  "#{base_override_loc_str(signature, super_signature)}"
@@ -200,7 +200,7 @@ module T::Private::Methods::SignatureValidation
200
200
  "#{base_override_loc_str(signature, super_signature)}"
201
201
  end
202
202
 
203
- if !signature.has_keyrest
203
+ if signature.keyrest_type.nil?
204
204
  # O(nm), but n and m are tiny here
205
205
  missing_kwargs = super_signature.kwarg_names - signature.kwarg_names
206
206
  if !missing_kwargs.empty?
@@ -210,7 +210,7 @@ module T::Private::Methods::SignatureValidation
210
210
  end
211
211
  end
212
212
 
213
- if !signature.has_keyrest && super_signature.has_keyrest
213
+ if signature.keyrest_type.nil? && !super_signature.keyrest_type.nil?
214
214
  raise "Your definition of `#{method_name}` must have `**#{super_signature.keyrest_name}` " \
215
215
  "to be compatible with the method it #{mode_verb}: " \
216
216
  "#{base_override_loc_str(signature, super_signature)}"
@@ -244,8 +244,8 @@ module T::Private::Methods::SignatureValidation
244
244
  if !super_type.subtype_of?(type)
245
245
  raise "Incompatible type for arg ##{index + 1} (`#{name}`) in signature for #{mode_noun} of method " \
246
246
  "`#{signature.method_name}`:\n" \
247
- "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \
248
- "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \
247
+ "* Base: `#{super_type}` (in #{super_signature.method_desc})\n" \
248
+ "* #{mode_noun.capitalize}: `#{type}` (in #{signature.method_desc})\n" \
249
249
  "(The types must be contravariant.)"
250
250
  end
251
251
  end
@@ -255,24 +255,24 @@ module T::Private::Methods::SignatureValidation
255
255
  type = signature.kwarg_types[name]
256
256
  if !super_type.subtype_of?(type)
257
257
  raise "Incompatible type for arg `#{name}` in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \
258
- "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \
259
- "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \
258
+ "* Base: `#{super_type}` (in #{super_signature.method_desc})\n" \
259
+ "* #{mode_noun.capitalize}: `#{type}` (in #{signature.method_desc})\n" \
260
260
  "(The types must be contravariant.)"
261
261
  end
262
262
  end
263
263
 
264
264
  # return types must be covariant
265
- super_signature_return_type = super_signature.return_type
265
+ super_signature_return_type = super_signature.effective_return_type
266
266
 
267
267
  if super_signature_return_type == T::Private::Types::Void::Private::INSTANCE
268
268
  # Treat `.void` as `T.anything` (see corresponding comment in definition_valitor for more)
269
269
  super_signature_return_type = T::Types::Anything::Private::INSTANCE
270
270
  end
271
271
 
272
- if !signature.return_type.subtype_of?(super_signature_return_type)
272
+ if !signature.effective_return_type.subtype_of?(super_signature_return_type)
273
273
  raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \
274
- "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \
275
- "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \
274
+ "* Base: `#{super_signature.effective_return_type}` (in #{super_signature.method_desc})\n" \
275
+ "* #{mode_noun.capitalize}: `#{signature.effective_return_type}` (in #{signature.method_desc})\n" \
276
276
  "(The types must be covariant.)"
277
277
  end
278
278
  end
@@ -297,14 +297,14 @@ module T::Private::Methods::SignatureValidation
297
297
 
298
298
  if visibility_strength(vis) > visibility_strength(super_vis)
299
299
  raise "Incompatible visibility for #{mode_noun} of method #{method.name}\n" \
300
- "* Base: #{super_vis} (in #{method_loc_str(super_method)})\n" \
301
- "* #{mode_noun.capitalize}: #{vis} (in #{method_loc_str(method)})\n" \
300
+ "* Base: #{super_vis} (in #{super_signature.method_desc})\n" \
301
+ "* #{mode_noun.capitalize}: #{vis} (in #{signature.method_desc})\n" \
302
302
  "(The override must be at least as permissive as the supermethod)" \
303
303
  end
304
304
  end
305
305
 
306
306
  private_class_method def self.method_visibility(method)
307
- T::Private::Methods.visibility_method_name(method.owner, method.name)
307
+ T::Private::ClassUtils.visibility_method_name(method.owner, method.name)
308
308
  end
309
309
 
310
310
  # Higher = more restrictive.
@@ -317,16 +317,7 @@ module T::Private::Methods::SignatureValidation
317
317
 
318
318
  private_class_method def self.base_override_loc_str(signature, super_signature)
319
319
  mode_noun = super_signature.mode == Modes.abstract ? 'Implementation' : 'Override'
320
- "\n * Base definition: in #{method_loc_str(super_signature.method)}" \
321
- "\n * #{mode_noun}: in #{method_loc_str(signature.method)}"
322
- end
323
-
324
- private_class_method def self.method_loc_str(method)
325
- loc = if method.source_location
326
- method.source_location.join(':')
327
- else
328
- "<unknown location>"
329
- end
330
- "#{method.owner} at #{loc}"
320
+ "\n * Base definition: in #{super_signature.method_desc}" \
321
+ "\n * #{mode_noun}: in #{signature.method_desc}"
331
322
  end
332
323
  end
data/lib/types/struct.rb CHANGED
@@ -10,7 +10,8 @@ end
10
10
  class T::Struct < T::InexactStruct
11
11
  def self.inherited(subclass)
12
12
  super(subclass)
13
- T::Private::ClassUtils.replace_method(subclass.singleton_class, :inherited, true) do |s|
13
+ original_method = subclass.singleton_class.instance_method(:inherited)
14
+ T::Private::ClassUtils.replace_method(original_method, subclass.singleton_class, :inherited) do |s|
14
15
  super(s)
15
16
  raise "#{self.name} is a subclass of T::Struct and cannot be subclassed"
16
17
  end
@@ -23,7 +24,8 @@ class T::ImmutableStruct < T::InexactStruct
23
24
  def self.inherited(subclass)
24
25
  super(subclass)
25
26
 
26
- T::Private::ClassUtils.replace_method(subclass.singleton_class, :inherited, true) do |s|
27
+ original_method = subclass.singleton_class.instance_method(:inherited)
28
+ T::Private::ClassUtils.replace_method(original_method, subclass.singleton_class, :inherited) do |s|
27
29
  super(s)
28
30
  raise "#{self.name} is a subclass of T::ImmutableStruct and cannot be subclassed"
29
31
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.12872
4
+ version: 0.6.13192
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-12-25 00:00:00.000000000 Z
11
+ date: 2026-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: benchmark
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: minitest
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -136,20 +150,6 @@ dependencies:
136
150
  - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: subprocess
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 1.5.3
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 1.5.3
153
153
  description: Sorbet's runtime type checking component
154
154
  email:
155
155
  executables: []