Skip to content

Commit e1e0f72

Browse files
committed
[IDE] Avoid redundant worklist visitor
This is unnecessary since the local conformances for a protocol can only contain self-conformances, which we don't want to visit anyway. This can just be a straightforward loop over the local conformances.
1 parent 831ed31 commit e1e0f72

File tree

3 files changed

+595
-610
lines changed

3 files changed

+595
-610
lines changed

lib/IDE/IDETypeChecking.cpp

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,6 @@ struct SynthesizedExtensionAnalyzer::Implementation {
480480

481481
ExtensionInfoMap InfoMap;
482482
ExtensionMergeInfoMap MergeInfoMap;
483-
std::vector<NominalTypeDecl*> Unhandled;
484483

485484
auto handleExtension = [&](ExtensionDecl *E, bool Synthesized,
486485
ExtensionDecl *EnablingE,
@@ -501,31 +500,17 @@ struct SynthesizedExtensionAnalyzer::Implementation {
501500
}
502501
};
503502

504-
// We want to visit the protocols of any normal conformances we see, but
505-
// we have to avoid doing this to self-conformances or we can end up with
506-
// a cycle. Otherwise this is cycle-proof on valid code.
507-
// We also want to ignore inherited conformances. Members from these will
508-
// be included in the class they were inherited from.
509-
auto addConformance = [&](ProtocolConformance *Conf) {
510-
if (isa<InheritedProtocolConformance>(Conf))
511-
return;
512-
auto RootConf = Conf->getRootConformance();
513-
if (isa<NormalProtocolConformance>(RootConf))
514-
Unhandled.push_back(RootConf->getProtocol());
515-
};
503+
for (auto *LocalConf : Target->getLocalConformances()) {
504+
if (isa<InheritedProtocolConformance>(LocalConf))
505+
continue;
516506

517-
for (auto *Conf : Target->getLocalConformances()) {
518-
addConformance(Conf);
519-
}
520-
while (!Unhandled.empty()) {
521-
NominalTypeDecl* Back = Unhandled.back();
522-
Unhandled.pop_back();
523-
for (ExtensionDecl *E : Back->getExtensions()) {
507+
auto RootConf = LocalConf->getRootConformance();
508+
auto *Conf = dyn_cast<NormalProtocolConformance>(RootConf);
509+
if (!Conf)
510+
continue;
511+
512+
for (auto *E : Conf->getProtocol()->getExtensions())
524513
handleExtension(E, true, nullptr, nullptr);
525-
}
526-
for (auto *Conf : Back->getLocalConformances()) {
527-
addConformance(Conf);
528-
}
529514
}
530515

531516
// Merge with actual extensions.

test/IDE/print_synthesized_extensions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ extension S13 : P5 {
241241
}
242242

243243
// CHECK1: <synthesized>extension <ref:Struct>S1</ref> where <ref:GenericTypeParam>T</ref> : <ref:module>print_synthesized_extensions</ref>.<ref:Protocol>P2</ref> {
244-
// CHECK1-NEXT: <decl:Func>public func <loc>p2member()</loc></decl>
245244
// CHECK1-NEXT: <decl:Func>public func <loc>ef1(<decl:Param>t: <ref:GenericTypeParam>T</ref></decl>)</loc></decl>
246245
// CHECK1-NEXT: <decl:Func>public func <loc>ef2(<decl:Param>t: <ref:module>print_synthesized_extensions</ref>.<ref:Struct>S2</ref></decl>)</loc></decl>
246+
// CHECK1-NEXT: <decl:Func>public func <loc>p2member()</loc></decl>
247247
// CHECK1-NEXT: }</synthesized>
248248

249249
// CHECK2: <synthesized>extension <ref:Struct>S1</ref> where <ref:GenericTypeParam>T</ref> : <ref:module>print_synthesized_extensions</ref>.<ref:Protocol>P3</ref> {
@@ -410,4 +410,4 @@ extension S14 : P14 where repeat each T: Hashable {}
410410

411411
// CHECK17: <synthesized>extension <ref:Struct>S14</ref> {
412412
// CHECK17-NEXT: <decl:Func>public func <loc>foo<each <ref:GenericTypeParam>T</ref>>(<decl:Param>_: repeat each <ref:GenericTypeParam>T</ref></decl>)</loc> where Pack{repeat each <ref:GenericTypeParam>T</ref>} : <ref:Protocol>Equatable</ref></decl>
413-
// CHECK17-NEXT: }</synthesized>
413+
// CHECK17-NEXT: }</synthesized>

0 commit comments

Comments
 (0)