@@ -122,38 +122,6 @@ const USRBasedType *USRBasedTypeArena::getVoidType() const { return VoidType; }
122
122
123
123
// MARK: - USRBasedType
124
124
125
- TypeRelation USRBasedType::typeRelationImpl (
126
- const USRBasedType *ResultType, const USRBasedType *VoidType,
127
- SmallPtrSetImpl<const USRBasedType *> &VisitedTypes) const {
128
-
129
- // `this` is the contextual type.
130
- if (this == VoidType) {
131
- // We don't report Void <-> Void matches because that would boost
132
- // methods returning Void in e.g.
133
- // func foo() { #^COMPLETE^# }
134
- // because #^COMPLETE^# is implicitly returned. But that's not very
135
- // helpful.
136
- return TypeRelation::Unknown;
137
- }
138
- if (ResultType == this ) {
139
- return TypeRelation::Convertible;
140
- }
141
- for (const USRBasedType *Supertype : ResultType->getSupertypes ()) {
142
- if (!VisitedTypes.insert (Supertype).second ) {
143
- // Already visited this type.
144
- continue ;
145
- }
146
- if (this ->typeRelation (Supertype, VoidType) >= TypeRelation::Convertible) {
147
- return TypeRelation::Convertible;
148
- }
149
- }
150
- // TypeRelation computation based on USRs is an under-approximation because we
151
- // don't take into account generic conversions or retroactive conformance of
152
- // library types. Hence, we can't know for sure that ResultType is not
153
- // convertible to `this` type and thus can't return Unrelated or Invalid here.
154
- return TypeRelation::Unknown;
155
- }
156
-
157
125
const USRBasedType *USRBasedType::null (USRBasedTypeArena &Arena) {
158
126
return USRBasedType::fromUSR (/* USR=*/ " " , /* Supertypes=*/ {}, {}, Arena);
159
127
}
@@ -337,8 +305,37 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
337
305
338
306
TypeRelation USRBasedType::typeRelation (const USRBasedType *ResultType,
339
307
const USRBasedType *VoidType) const {
340
- SmallPtrSet<const USRBasedType *, 4 > VisitedTypes;
341
- return this ->typeRelationImpl (ResultType, VoidType, VisitedTypes);
308
+ // `this` is the contextual type.
309
+ if (this == VoidType) {
310
+ // We don't report Void <-> Void matches because that would boost
311
+ // methods returning Void in e.g.
312
+ // func foo() { #^COMPLETE^# }
313
+ // because #^COMPLETE^# is implicitly returned. But that's not very
314
+ // helpful.
315
+ return TypeRelation::Unknown;
316
+ }
317
+
318
+ SmallPtrSet<const USRBasedType *, 16 > VisitedTypes;
319
+ SmallVector<const USRBasedType *, 16 > Worklist;
320
+ Worklist.push_back (ResultType);
321
+ while (!Worklist.empty ()) {
322
+ auto *CurrentType = Worklist.pop_back_val ();
323
+ if (CurrentType == this )
324
+ return TypeRelation::Convertible;
325
+
326
+ for (const USRBasedType *Supertype : CurrentType->getSupertypes ()) {
327
+ if (!VisitedTypes.insert (Supertype).second ) {
328
+ // Already visited this type.
329
+ continue ;
330
+ }
331
+ Worklist.push_back (Supertype);
332
+ }
333
+ }
334
+ // TypeRelation computation based on USRs is an under-approximation because we
335
+ // don't take into account generic conversions or retroactive conformance of
336
+ // library types. Hence, we can't know for sure that ResultType is not
337
+ // convertible to `this` type and thus can't return Unrelated or Invalid here.
338
+ return TypeRelation::Unknown;
342
339
}
343
340
344
341
// MARK: - USRBasedTypeContext
0 commit comments