@@ -82,133 +82,59 @@ static const unsigned TypeDepthThreshold = 50;
82
82
// / Set the width threshold rather high, because some projects uses very wide
83
83
// / tuples to model fixed size arrays.
84
84
static const unsigned TypeWidthThreshold = 2000 ;
85
+ // / Max length of an opaque archetype's type parameter.
86
+ static const unsigned TypeLengthThreshold = 10 ;
85
87
86
88
// / Compute the width and the depth of a type.
87
89
// / We compute both, because some pathological test-cases result in very
88
90
// / wide types and some others result in very deep types. It is important
89
91
// / to bail as soon as we hit the threshold on any of both dimensions to
90
92
// / prevent compiler hangs and crashes.
91
- static std::pair<unsigned , unsigned > getTypeDepthAndWidth (Type t) {
92
- unsigned Depth = 0 ;
93
- unsigned Width = 0 ;
94
- if (auto *BGT = t->getAs <BoundGenericType>()) {
95
- auto *NTD = BGT->getNominalOrBoundGenericNominal ();
96
- if (NTD) {
97
- auto StoredProperties = NTD->getStoredProperties ();
98
- Width += StoredProperties.size ();
99
- }
100
- ++Depth;
101
- unsigned MaxTypeDepth = 0 ;
102
- auto GenericArgs = BGT->getGenericArgs ();
103
- for (auto Ty : GenericArgs) {
104
- unsigned TypeWidth;
105
- unsigned TypeDepth;
106
- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (Ty);
107
- if (TypeDepth > MaxTypeDepth)
108
- MaxTypeDepth = TypeDepth;
109
- Width += TypeWidth;
110
- }
111
- Depth += MaxTypeDepth;
112
- return std::make_pair (Depth, Width);
113
- }
114
-
115
- if (auto *TupleTy = t->getAs <TupleType>()) {
116
- Width += TupleTy->getNumElements ();
117
- ++Depth;
118
- unsigned MaxTypeDepth = 0 ;
119
- auto ElementTypes = TupleTy->getElementTypes ();
120
- for (auto Ty : ElementTypes) {
121
- unsigned TypeWidth;
122
- unsigned TypeDepth;
123
- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (Ty);
124
- if (TypeDepth > MaxTypeDepth)
125
- MaxTypeDepth = TypeDepth;
126
- Width += TypeWidth;
127
- }
128
- Depth += MaxTypeDepth;
129
- return std::make_pair (Depth, Width);
130
- }
131
-
132
- if (auto *FnTy = t->getAs <SILFunctionType>()) {
133
- ++Depth;
134
- unsigned MaxTypeDepth = 0 ;
135
- auto Params = FnTy->getParameters ();
136
- Width += Params.size ();
137
- for (auto Param : Params) {
138
- unsigned TypeWidth;
139
- unsigned TypeDepth;
140
- std::tie (TypeDepth, TypeWidth) =
141
- getTypeDepthAndWidth (Param.getInterfaceType ());
142
- if (TypeDepth > MaxTypeDepth)
143
- MaxTypeDepth = TypeDepth;
144
- Width += TypeWidth;
145
- }
146
- auto Results = FnTy->getResults ();
147
- Width += Results.size ();
148
- for (auto Result : Results) {
149
- unsigned TypeWidth;
150
- unsigned TypeDepth;
151
- std::tie (TypeDepth, TypeWidth) =
152
- getTypeDepthAndWidth (Result.getInterfaceType ());
153
- if (TypeDepth > MaxTypeDepth)
154
- MaxTypeDepth = TypeDepth;
155
- Width += TypeWidth;
156
- }
157
- if (FnTy->hasErrorResult ()) {
158
- Width += 1 ;
159
- unsigned TypeWidth;
160
- unsigned TypeDepth;
161
- std::tie (TypeDepth, TypeWidth) =
162
- getTypeDepthAndWidth (FnTy->getErrorResult ().getInterfaceType ());
163
- if (TypeDepth > MaxTypeDepth)
164
- MaxTypeDepth = TypeDepth;
165
- Width += TypeWidth;
166
- }
167
- Depth += MaxTypeDepth;
168
- return std::make_pair (Depth, Width);
169
- }
170
-
171
- if (auto *FnTy = t->getAs <FunctionType>()) {
172
- ++Depth;
173
- unsigned MaxTypeDepth = 0 ;
174
- auto Params = FnTy->getParams ();
175
- Width += Params.size ();
176
- for (auto &Param : Params) {
177
- unsigned TypeWidth;
178
- unsigned TypeDepth;
179
- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (Param.getParameterType ());
180
- if (TypeDepth > MaxTypeDepth)
181
- MaxTypeDepth = TypeDepth;
182
- Width += TypeWidth;
183
- }
184
- unsigned TypeWidth;
185
- unsigned TypeDepth;
186
- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (FnTy->getResult ());
187
- if (TypeDepth > MaxTypeDepth)
188
- MaxTypeDepth = TypeDepth;
189
- Width += TypeWidth;
190
- Depth += MaxTypeDepth;
191
- return std::make_pair (Depth, Width);
192
- }
193
-
194
- if (auto *MT = t->getAs <MetatypeType>()) {
195
- Depth += 1 ;
196
- unsigned TypeWidth;
197
- unsigned TypeDepth;
198
- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (MT->getInstanceType ());
199
- Width += TypeWidth;
200
- Depth += TypeDepth;
201
- return std::make_pair (Depth, Width);
202
- }
203
-
204
- return std::make_pair (Depth, Width);
205
- }
206
-
207
93
static bool isTypeTooComplex (Type t) {
208
- unsigned TypeWidth;
209
- unsigned TypeDepth;
210
- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (t);
211
- return TypeWidth >= TypeWidthThreshold || TypeDepth >= TypeDepthThreshold;
94
+ struct Walker : TypeWalker {
95
+ unsigned Depth = 0 ;
96
+ unsigned MaxDepth = 0 ;
97
+ unsigned MaxWidth = 0 ;
98
+ unsigned MaxLength = 0 ;
99
+
100
+ Action walkToTypePre (Type ty) override {
101
+ // The TypeWalker won't visit the interface type encapsulated by the
102
+ // archetype, so we do it directly to measure its length.
103
+ if (auto *opaqueArchetypeTy = ty->getAs <OpaqueTypeArchetypeType>()) {
104
+ auto interfaceTy = opaqueArchetypeTy->getInterfaceType ();
105
+
106
+ unsigned length = 0 ;
107
+ while (auto memberTy = interfaceTy->getAs <DependentMemberType>()) {
108
+ ++length;
109
+ interfaceTy = memberTy->getBase ();
110
+ }
111
+ assert (interfaceTy->is <GenericTypeParamType>());
112
+
113
+ if (length > MaxLength)
114
+ MaxLength = length;
115
+ }
116
+
117
+ ++Depth;
118
+ MaxDepth = std::max (Depth, MaxDepth);
119
+
120
+ ++MaxWidth;
121
+
122
+ return Action::Continue;
123
+ }
124
+
125
+ Action walkToTypePost (Type ty) override {
126
+ --Depth;
127
+
128
+ return Action::Continue;
129
+ }
130
+ };
131
+
132
+ Walker walker;
133
+ t.walk (walker);
134
+
135
+ return (walker.MaxWidth >= TypeWidthThreshold ||
136
+ walker.MaxDepth >= TypeDepthThreshold ||
137
+ walker.MaxLength >= TypeLengthThreshold);
212
138
}
213
139
214
140
namespace {
0 commit comments