@@ -122,38 +122,6 @@ const USRBasedType *USRBasedTypeArena::getVoidType() const { return VoidType; }
122122
123123// MARK: - USRBasedType
124124
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-
157125const USRBasedType *USRBasedType::null (USRBasedTypeArena &Arena) {
158126 return USRBasedType::fromUSR (/* USR=*/ " " , /* Supertypes=*/ {}, {}, Arena);
159127}
@@ -337,8 +305,37 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
337305
338306TypeRelation USRBasedType::typeRelation (const USRBasedType *ResultType,
339307 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;
342339}
343340
344341// MARK: - USRBasedTypeContext
0 commit comments