@@ -6,7 +6,7 @@ module Runtime
66 # This class is responsible for storing and looking up information related to generic types.
77 #
88 # The class stores 2 different kinds of data, in two separate lookup tables:
9- # 1. a lookup of generic type instances by name: `@generic_instances`
9+ # 1. a lookup of generic type instances by constant and name: `@generic_instances`
1010 # 2. a lookup of type variable serializer by constant and type variable
1111 # instance: `@type_variables`
1212 #
@@ -21,7 +21,7 @@ module Runtime
2121 # variable to type variable serializers. This allows us to associate type variables
2222 # to the constant names that represent them, easily.
2323 module GenericTypeRegistry
24- @generic_instances = { } #: Hash[String, Module[top]]
24+ @generic_instances = { } . compare_by_identity #: Hash[Module[top], Hash[ String, Module[top] ]]
2525
2626 @type_variables = { } . compare_by_identity #: Hash[Module[top], Array[TypeVariableModule]]
2727
@@ -45,8 +45,9 @@ class << self
4545 # and cloning the given constant so that we can return a type that is the same
4646 # as the current type but is a different instance and has a different name method.
4747 #
48- # We cache those cloned instances by their name in `@generic_instances`, so that
49- # we don't keep instantiating a new type every single time it is referenced.
48+ # We cache those cloned instances by their original constant and their name in
49+ # `@generic_instances`, so that we don't keep instantiating a new type every single
50+ # time it is referenced.
5051 # For example, `[Foo[Integer], Foo[Integer], Foo[Integer], Foo[String]]` will only
5152 # result in 2 clones (1 for `Foo[Integer]` and another for `Foo[String]`) and
5253 # 2 hash lookups (for the other two `Foo[Integer]`s).
@@ -64,12 +65,15 @@ def register_type(constant, types)
6465 #
6566 # Also, we try to memoize the generic type based on the name, so that
6667 # we don't have to keep recreating them all the time.
67- @generic_instances [ name ] ||= create_generic_type ( constant , name )
68+ generic_instances = @generic_instances [ constant ] ||= { }
69+ generic_instances [ name ] ||= create_generic_type ( constant , name )
6870 end
6971
7072 #: (Object instance) -> bool
7173 def generic_type_instance? ( instance )
72- @generic_instances . values . any? { |generic_type | generic_type === instance }
74+ @generic_instances . values . any? do |generic_instances |
75+ generic_instances . values . any? { |generic_type | generic_type === instance }
76+ end
7377 end
7478
7579 #: (Module[top] constant) -> Array[TypeVariableModule]?
@@ -88,7 +92,7 @@ def lookup_type_variables(constant)
8892 # can return it from the original methods as well.
8993 #: (untyped constant, TypeVariableModule type_variable) -> void
9094 def register_type_variable ( constant , type_variable )
91- type_variables = lookup_or_initialize_type_variables ( constant )
95+ type_variables = @type_variables [ constant ] ||= [ ]
9296
9397 type_variables << type_variable
9498 end
@@ -163,11 +167,6 @@ def create_safe_subclass(constant)
163167 owner . send ( :define_method , :inherited , inherited_method )
164168 end
165169 end
166-
167- #: (Module[top] constant) -> Array[TypeVariableModule]
168- def lookup_or_initialize_type_variables ( constant )
169- @type_variables [ constant ] ||= [ ]
170- end
171170 end
172171 end
173172 end
0 commit comments