@@ -77,6 +77,19 @@ class GenericTypeRegistrySpec < Minitest::Spec
77
77
refute_same ( result , RaisesInInheritedCallback )
78
78
assert_operator ( result , :< , RaisesInInheritedCallback )
79
79
end
80
+
81
+ it "works for classes that specify a 'loose' sig on .inherited" do
82
+ # By "loose", we mean `T::Class[T.anything]` instead of `T::Class[SampleGenericClass[T.anything]]`
83
+ _ = HasNonRecursiveInheritedSig [ Object ]
84
+ end
85
+
86
+ it "FIXME: breaks from infinite recursion if the sig on .inherited uses the generic type" do
87
+ # Our swizzled implementation of the `.inherited` method needs to be carefully implemented to not fall into
88
+ # infinite recursion when the sig for the method references the class that it's defined on.
89
+ assert_raises ( SystemStackError ) do
90
+ HasRecursiveInheritedSig [ Object ]
91
+ end
92
+ end
80
93
end
81
94
end
82
95
@@ -98,6 +111,39 @@ def inherited(subclass)
98
111
end
99
112
end
100
113
end
114
+
115
+ class HasNonRecursiveInheritedSig
116
+ extend T ::Generic
117
+
118
+ Element = type_member
119
+
120
+ class << self
121
+ extend T ::Sig
122
+
123
+ # The correct type would be `T::Class[SampleGenericClass[T.anything]]`, but that would crash Tapioca.
124
+ # That's not honey Pooh, that's recursion!
125
+ sig { params ( subclass : T ::Class [ T . anything ] ) . void }
126
+ def inherited ( subclass )
127
+ super
128
+ end
129
+ end
130
+ end
131
+
132
+ class HasRecursiveInheritedSig
133
+ extend T ::Generic
134
+
135
+ Element = type_member
136
+
137
+ class << self
138
+ extend T ::Sig
139
+
140
+ # This sig references an instantiation of this class itself.
141
+ sig { params ( subclass : T ::Class [ HasRecursiveInheritedSig [ T . anything ] ] ) . void }
142
+ def inherited ( subclass )
143
+ super
144
+ end
145
+ end
146
+ end
101
147
end
102
148
end
103
149
end
0 commit comments