sorbet-runtime 0.5.10461 → 0.5.10473

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad78cb1ef08fe9a8f5ac0fe6f69d56ee931dc7768b21761177ea093153a00f7a
4
- data.tar.gz: befebc526f225a590a907eac2b05270c09c62c9be7cd59b3a4a14d8f2fc183ac
3
+ metadata.gz: b189a0adf5472e2cae48a050abe2697c03c44048fd3c59b1f104928ed09771d2
4
+ data.tar.gz: 7aa59c471cf94a8539c610c96b11f36884da152d2b6e37e6f8fb630c781b51fb
5
5
  SHA512:
6
- metadata.gz: 9aa012c622c636cef39a643ce67d0ab5df6ea20326cdc5564c82ca278407ae629e3b786d46ebaee41e79dc533e92bbe08e3f41c23af0a4e12fcfb097a87df245
7
- data.tar.gz: 52ee3c205e58e786cab5d1eaa7a4f94addce8a29f6822ca133c55fd817b22666d7bfb8d9bd95ff6e8edada7f442aa07100ce6c8edbfd24b448fc5942d4eff38c
6
+ metadata.gz: 8cfcd118c9529eb878a9838deb129d246c7594030553a448116b6f6c30250476367aa2a19ff3b555ba58398b25827fbb7d3d82c45ef267d01076f6810bdcf95d
7
+ data.tar.gz: 8848028f5f9dd560ce4600a8ff8ead2bf9eb05dc969897bc714f6a6868e5f73fbb36ed3c73979da0f01ead482d1f4a5c4bb0b1d04edde09190f5ba26f6ed1af8
@@ -55,6 +55,7 @@ require_relative 'types/private/types/not_typed'
55
55
  require_relative 'types/private/types/void'
56
56
  require_relative 'types/private/types/string_holder'
57
57
  require_relative 'types/private/types/type_alias'
58
+ require_relative 'types/private/types/simple_pair_union'
58
59
 
59
60
  require_relative 'types/types/type_variable'
60
61
  require_relative 'types/types/type_member'
data/lib/types/_types.rb CHANGED
@@ -221,6 +221,34 @@ module T
221
221
  end
222
222
  end
223
223
 
224
+ # A convenience method to `raise` with a provided error reason when the argument
225
+ # is `nil` and return it otherwise.
226
+ #
227
+ # Intended to be used as:
228
+ #
229
+ # needs_foo(T.must_because(maybe_gives_foo) {"reason_foo_should_not_be_nil"})
230
+ #
231
+ # Equivalent to:
232
+ #
233
+ # foo = maybe_gives_foo
234
+ # raise "reason_foo_should_not_be_nil" if foo.nil?
235
+ # needs_foo(foo)
236
+ #
237
+ # Intended to be used to promise sorbet that a given nilable value happens
238
+ # to contain a non-nil value at this point.
239
+ #
240
+ # `sig {params(arg: T.nilable(A), reason_blk: T.proc.returns(String)).returns(A)}`
241
+ def self.must_because(arg)
242
+ return arg if arg
243
+ return arg if arg == false
244
+
245
+ begin
246
+ raise TypeError.new("Unexpected `nil` because #{yield}")
247
+ rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
248
+ T::Configuration.inline_type_error_handler(e, {kind: 'T.must_because', value: arg, type: nil})
249
+ end
250
+ end
251
+
224
252
  # A way to ask Sorbet to show what type it thinks an expression has.
225
253
  # This can be useful for debugging and checking assumptions.
226
254
  # In the runtime, merely returns the value passed in.
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ # Specialization of Union for the common case of the union of two simple types.
5
+ #
6
+ # This covers e.g. T.nilable(SomeModule), T.any(Integer, Float), and T::Boolean.
7
+ class T::Private::Types::SimplePairUnion < T::Types::Union
8
+ class DuplicateType < RuntimeError; end
9
+
10
+ # @param type_a [T::Types::Simple]
11
+ # @param type_b [T::Types::Simple]
12
+ def initialize(type_a, type_b)
13
+ if type_a == type_b
14
+ raise DuplicateType.new("#{type_a} == #{type_b}")
15
+ end
16
+
17
+ @raw_a = type_a.raw_type
18
+ @raw_b = type_b.raw_type
19
+ end
20
+
21
+ # @override Union
22
+ def recursively_valid?(obj)
23
+ obj.is_a?(@raw_a) || obj.is_a?(@raw_b)
24
+ end
25
+
26
+ # @override Union
27
+ def valid?(obj)
28
+ obj.is_a?(@raw_a) || obj.is_a?(@raw_b)
29
+ end
30
+
31
+ # @override Union
32
+ def types
33
+ # We reconstruct the simple types rather than just storing them because
34
+ # (1) this is normally not a hot path and (2) we want to keep the instance
35
+ # variable count <= 3 so that we can fit in a 40 byte heap entry along
36
+ # with object headers.
37
+ @types ||= [
38
+ T::Types::Simple::Private::Pool.type_for_module(@raw_a),
39
+ T::Types::Simple::Private::Pool.type_for_module(@raw_b),
40
+ ]
41
+ end
42
+ end
@@ -163,8 +163,12 @@ module T::Types
163
163
  # Type equivalence, defined by serializing the type to a string (with
164
164
  # `#name`) and comparing the resulting strings for equality.
165
165
  def ==(other)
166
- (T::Utils.resolve_alias(other).class == T::Utils.resolve_alias(self).class) &&
166
+ case other
167
+ when T::Types::Base
167
168
  other.name == self.name
169
+ else
170
+ false
171
+ end
168
172
  end
169
173
 
170
174
  alias_method :eql?, :==
@@ -52,7 +52,10 @@ module T::Types
52
52
  end
53
53
 
54
54
  def to_nilable
55
- @nilable ||= T::Types::Union.new([self, T::Utils::Nilable::NIL_TYPE])
55
+ @nilable ||= T::Private::Types::SimplePairUnion.new(
56
+ self,
57
+ T::Utils::Nilable::NIL_TYPE,
58
+ )
56
59
  end
57
60
 
58
61
  module Private
@@ -6,6 +6,8 @@ module T::Types
6
6
  class Union < Base
7
7
  attr_reader :types
8
8
 
9
+ # Don't use Union.new directly, use `Private::Pool.union_of_types`
10
+ # inside sorbet-runtime and `T.any` elsewhere.
9
11
  def initialize(types)
10
12
  @types = types.flat_map do |type|
11
13
  type = T::Utils.coerce(type)
@@ -20,11 +22,16 @@ module T::Types
20
22
 
21
23
  # overrides Base
22
24
  def name
23
- type_shortcuts(@types)
25
+ # Use the attr_reader here so we can override it in SimplePairUnion
26
+ type_shortcuts(types)
24
27
  end
25
28
 
26
29
  private def type_shortcuts(types)
27
30
  if types.size == 1
31
+ # We shouldn't generally get here but it's possible if initializing the type
32
+ # evades Sorbet's static check and we end up on the slow path, or if someone
33
+ # is using the T:Types::Union constructor directly (the latter possibility
34
+ # is why we don't just move the `uniq` into `Private::Pool.union_of_types`).
28
35
  return types[0].name
29
36
  end
30
37
  nilable = T::Utils.coerce(NilClass)
@@ -62,27 +69,45 @@ module T::Types
62
69
  EMPTY_ARRAY = [].freeze
63
70
  private_constant :EMPTY_ARRAY
64
71
 
72
+ # Try to use `to_nilable` on a type to get memoization, or failing that
73
+ # try to at least use SimplePairUnion to get faster init and typechecking.
74
+ #
75
+ # We aren't guaranteed to detect a simple `T.nilable(<Module>)` type here
76
+ # in cases where there are duplicate types, nested unions, etc.
77
+ #
78
+ # That's ok, because returning is SimplePairUnion an optimization which
79
+ # isn't necessary for correctness.
80
+ #
65
81
  # @param type_a [T::Types::Base]
66
82
  # @param type_b [T::Types::Base]
67
83
  # @param types [Array] optional array of additional T::Types::Base instances
68
84
  def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY)
69
- if types.empty?
70
- # We aren't guaranteed to detect a simple `T.nilable(<Module>)` type here
71
- # in cases where there are duplicate types, nested unions, etc.
72
- #
73
- # That's ok, because this is an optimization which isn't necessary for
74
- # correctness.
75
- if type_b == T::Utils::Nilable::NIL_TYPE && type_a.is_a?(T::Types::Simple)
85
+ if !types.empty?
86
+ # Slow path
87
+ return Union.new([type_a, type_b] + types)
88
+ elsif !type_a.is_a?(T::Types::Simple) || !type_b.is_a?(T::Types::Simple)
89
+ # Slow path
90
+ return Union.new([type_a, type_b])
91
+ end
92
+
93
+ begin
94
+ if type_b == T::Utils::Nilable::NIL_TYPE
76
95
  type_a.to_nilable
77
- elsif type_a == T::Utils::Nilable::NIL_TYPE && type_b.is_a?(T::Types::Simple)
96
+ elsif type_a == T::Utils::Nilable::NIL_TYPE
78
97
  type_b.to_nilable
79
98
  else
80
- Union.new([type_a, type_b])
99
+ T::Private::Types::SimplePairUnion.new(type_a, type_b)
81
100
  end
82
- else
83
- # This can't be a `T.nilable(<Module>)` case unless there are duplicates,
84
- # which is possible but unexpected.
85
- Union.new([type_a, type_b] + types)
101
+ rescue T::Private::Types::SimplePairUnion::DuplicateType
102
+ # Slow path
103
+ #
104
+ # This shouldn't normally be possible due to static checks,
105
+ # but we can get here if we're constructing a type dynamically.
106
+ #
107
+ # Relying on the duplicate check in the constructor has the
108
+ # advantage that we avoid it when we hit the memoized case
109
+ # of `to_nilable`.
110
+ type_a
86
111
  end
87
112
  end
88
113
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.10461
4
+ version: 0.5.10473
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-28 00:00:00.000000000 Z
11
+ date: 2022-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -151,7 +151,7 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: 1.5.3
153
153
  description: Sorbet's runtime type checking component
154
- email:
154
+ email:
155
155
  executables: []
156
156
  extensions: []
157
157
  extra_rdoc_files: []
@@ -189,6 +189,7 @@ files:
189
189
  - lib/types/private/runtime_levels.rb
190
190
  - lib/types/private/sealed.rb
191
191
  - lib/types/private/types/not_typed.rb
192
+ - lib/types/private/types/simple_pair_union.rb
192
193
  - lib/types/private/types/string_holder.rb
193
194
  - lib/types/private/types/type_alias.rb
194
195
  - lib/types/private/types/void.rb
@@ -245,7 +246,7 @@ licenses:
245
246
  - Apache-2.0
246
247
  metadata:
247
248
  source_code_uri: https://github.com/sorbet/sorbet
248
- post_install_message:
249
+ post_install_message:
249
250
  rdoc_options: []
250
251
  require_paths:
251
252
  - lib
@@ -253,15 +254,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
253
254
  requirements:
254
255
  - - ">="
255
256
  - !ruby/object:Gem::Version
256
- version: 2.3.0
257
+ version: 2.7.0
257
258
  required_rubygems_version: !ruby/object:Gem::Requirement
258
259
  requirements:
259
260
  - - ">="
260
261
  - !ruby/object:Gem::Version
261
262
  version: '0'
262
263
  requirements: []
263
- rubygems_version: 3.1.4
264
- signing_key:
264
+ rubygems_version: 3.3.7
265
+ signing_key:
265
266
  specification_version: 4
266
267
  summary: Sorbet runtime
267
268
  test_files: []