Skip to content

Commit 8a6e07d

Browse files
authored
Merge pull request #36223 from DougGregor/lookup-all-conformances-request
2 parents d4300dd + 114f856 commit 8a6e07d

File tree

8 files changed

+66
-90
lines changed

8 files changed

+66
-90
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,6 +3004,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
30043004
friend class DeclContext;
30053005
friend class IterableDeclContext;
30063006
friend class DirectLookupRequest;
3007+
friend class LookupAllConformancesInContextRequest;
30073008
friend ArrayRef<ValueDecl *>
30083009
ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const;
30093010

include/swift/AST/DeclContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ class IterableDeclContext {
734734

735735
static IterableDeclContext *castDeclToIterableDeclContext(const Decl *D);
736736

737+
friend class LookupAllConformancesInContextRequest;
738+
737739
/// Retrieve the \c ASTContext in which this iterable context occurs.
738740
ASTContext &getASTContext() const;
739741

lib/AST/ConformanceLookupTable.cpp

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -955,9 +955,7 @@ bool ConformanceLookupTable::lookupConformance(
955955
void ConformanceLookupTable::lookupConformances(
956956
NominalTypeDecl *nominal,
957957
DeclContext *dc,
958-
ConformanceLookupKind lookupKind,
959-
SmallVectorImpl<ProtocolDecl *> *protocols,
960-
SmallVectorImpl<ProtocolConformance *> *conformances,
958+
std::vector<ProtocolConformance *> *conformances,
961959
SmallVectorImpl<ConformanceDiagnostic> *diagnostics) {
962960
// We need to expand all implied conformances before we can find
963961
// those conformances that pertain to this declaration context.
@@ -980,36 +978,6 @@ void ConformanceLookupTable::lookupConformances(
980978
if (entry->isSuperseded())
981979
return true;
982980

983-
// If we are to filter out this result, do so now.
984-
switch (lookupKind) {
985-
case ConformanceLookupKind::OnlyExplicit:
986-
switch (entry->getKind()) {
987-
case ConformanceEntryKind::Explicit:
988-
case ConformanceEntryKind::Synthesized:
989-
break;
990-
case ConformanceEntryKind::Implied:
991-
case ConformanceEntryKind::Inherited:
992-
return false;
993-
}
994-
break;
995-
case ConformanceLookupKind::NonInherited:
996-
switch (entry->getKind()) {
997-
case ConformanceEntryKind::Explicit:
998-
case ConformanceEntryKind::Synthesized:
999-
case ConformanceEntryKind::Implied:
1000-
break;
1001-
case ConformanceEntryKind::Inherited:
1002-
return false;
1003-
}
1004-
break;
1005-
case ConformanceLookupKind::All:
1006-
break;
1007-
}
1008-
1009-
// Record the protocol.
1010-
if (protocols)
1011-
protocols->push_back(entry->getProtocol());
1012-
1013981
// Record the conformance.
1014982
if (conformances) {
1015983
if (auto conformance = getConformance(nominal, entry))

lib/AST/ConformanceLookupTable.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,7 @@ class ConformanceLookupTable {
437437
/// Look for all of the conformances within the given declaration context.
438438
void lookupConformances(NominalTypeDecl *nominal,
439439
DeclContext *dc,
440-
ConformanceLookupKind lookupKind,
441-
SmallVectorImpl<ProtocolDecl *> *protocols,
442-
SmallVectorImpl<ProtocolConformance *> *conformances,
440+
std::vector<ProtocolConformance *> *conformances,
443441
SmallVectorImpl<ConformanceDiagnostic> *diagnostics);
444442

445443
/// Retrieve the complete set of protocols to which this nominal

lib/AST/ProtocolConformance.cpp

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,59 +1321,83 @@ NominalTypeDecl::getSatisfiedProtocolRequirementsForMember(
13211321
SmallVector<ProtocolDecl *, 2>
13221322
IterableDeclContext::getLocalProtocols(ConformanceLookupKind lookupKind) const {
13231323
SmallVector<ProtocolDecl *, 2> result;
1324-
1325-
// Dig out the nominal type.
1326-
const auto dc = getAsGenericContext();
1327-
const auto nominal = dc->getSelfNominalTypeDecl();
1328-
if (!nominal) {
1329-
return result;
1330-
}
1331-
1332-
// Update to record all potential conformances.
1333-
nominal->prepareConformanceTable();
1334-
nominal->ConformanceTable->lookupConformances(
1335-
nominal,
1336-
const_cast<GenericContext *>(dc),
1337-
lookupKind,
1338-
&result,
1339-
nullptr,
1340-
nullptr);
1341-
1324+
for (auto conformance : getLocalConformances(lookupKind))
1325+
result.push_back(conformance->getProtocol());
13421326
return result;
13431327
}
13441328

1345-
SmallVector<ProtocolConformance *, 2>
1346-
IterableDeclContext::getLocalConformances(ConformanceLookupKind lookupKind)
1347-
const {
1348-
SmallVector<ProtocolConformance *, 2> result;
1349-
1329+
std::vector<ProtocolConformance *>
1330+
LookupAllConformancesInContextRequest::evaluate(
1331+
Evaluator &eval, const IterableDeclContext *IDC) const {
13501332
// Dig out the nominal type.
1351-
const auto dc = getAsGenericContext();
1333+
const auto dc = IDC->getAsGenericContext();
13521334
const auto nominal = dc->getSelfNominalTypeDecl();
13531335
if (!nominal) {
1354-
return result;
1336+
return { };
13551337
}
13561338

13571339
// Protocols only have self-conformances.
13581340
if (auto protocol = dyn_cast<ProtocolDecl>(nominal)) {
13591341
if (protocol->requiresSelfConformanceWitnessTable()) {
1360-
return SmallVector<ProtocolConformance *, 2>{
1361-
protocol->getASTContext().getSelfConformance(protocol)
1362-
};
1342+
return { protocol->getASTContext().getSelfConformance(protocol) };
13631343
}
1364-
return SmallVector<ProtocolConformance *, 2>();
1344+
1345+
return { };
13651346
}
13661347

1367-
// Update to record all potential conformances.
1348+
// Record all potential conformances.
13681349
nominal->prepareConformanceTable();
1350+
std::vector<ProtocolConformance *> conformances;
13691351
nominal->ConformanceTable->lookupConformances(
13701352
nominal,
13711353
const_cast<GenericContext *>(dc),
1372-
lookupKind,
1373-
nullptr,
1374-
&result,
1354+
&conformances,
13751355
nullptr);
13761356

1357+
return conformances;
1358+
}
1359+
1360+
SmallVector<ProtocolConformance *, 2>
1361+
IterableDeclContext::getLocalConformances(ConformanceLookupKind lookupKind)
1362+
const {
1363+
// Look up the cached set of all of the conformances.
1364+
std::vector<ProtocolConformance *> conformances =
1365+
evaluateOrDefault(
1366+
getASTContext().evaluator, LookupAllConformancesInContextRequest{this},
1367+
{ });
1368+
1369+
// Copy all of the conformances we want.
1370+
SmallVector<ProtocolConformance *, 2> result;
1371+
std::copy_if(
1372+
conformances.begin(), conformances.end(), std::back_inserter(result),
1373+
[&](ProtocolConformance *conformance) {
1374+
// If we are to filter out this result, do so now.
1375+
switch (lookupKind) {
1376+
case ConformanceLookupKind::OnlyExplicit:
1377+
switch (conformance->getSourceKind()) {
1378+
case ConformanceEntryKind::Explicit:
1379+
case ConformanceEntryKind::Synthesized:
1380+
return true;
1381+
case ConformanceEntryKind::Implied:
1382+
case ConformanceEntryKind::Inherited:
1383+
return false;
1384+
}
1385+
1386+
case ConformanceLookupKind::NonInherited:
1387+
switch (conformance->getSourceKind()) {
1388+
case ConformanceEntryKind::Explicit:
1389+
case ConformanceEntryKind::Synthesized:
1390+
case ConformanceEntryKind::Implied:
1391+
return true;
1392+
case ConformanceEntryKind::Inherited:
1393+
return false;
1394+
}
1395+
1396+
case ConformanceLookupKind::All:
1397+
return true;
1398+
}
1399+
});
1400+
13771401
return result;
13781402
}
13791403

@@ -1399,8 +1423,6 @@ IterableDeclContext::takeConformanceDiagnostics() const {
13991423
nominal->ConformanceTable->lookupConformances(
14001424
nominal,
14011425
const_cast<GenericContext *>(dc),
1402-
ConformanceLookupKind::All,
1403-
nullptr,
14041426
nullptr,
14051427
&result);
14061428

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,7 @@ bool IsAsyncHandlerRequest::evaluate(
178178
// implies @asyncHandler.
179179
{
180180
auto idc = cast<IterableDeclContext>(dc->getAsDecl());
181-
auto conformances = evaluateOrDefault(
182-
dc->getASTContext().evaluator,
183-
LookupAllConformancesInContextRequest{idc}, { });
181+
auto conformances = idc->getLocalConformances();
184182

185183
for (auto conformance : conformances) {
186184
auto protocol = conformance->getProtocol();
@@ -2050,9 +2048,7 @@ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements(
20502048

20512049
// Walk through each of the conformances in this context, collecting any
20522050
// requirements that have actor isolation.
2053-
auto conformances = evaluateOrDefault(
2054-
dc->getASTContext().evaluator,
2055-
LookupAllConformancesInContextRequest{idc}, { });
2051+
auto conformances = idc->getLocalConformances();
20562052
using IsolatedRequirement =
20572053
std::tuple<ProtocolConformance *, ActorIsolation, ValueDecl *>;
20582054
SmallVector<IsolatedRequirement, 2> isolatedRequirements;

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5650,13 +5650,6 @@ diagnoseMissingAppendInterpolationMethod(NominalTypeDecl *typeDecl) {
56505650
}
56515651
}
56525652

5653-
std::vector<ProtocolConformance *>
5654-
LookupAllConformancesInContextRequest::evaluate(
5655-
Evaluator &eval, const IterableDeclContext *IDC) const {
5656-
auto result = IDC->getLocalConformances(ConformanceLookupKind::All);
5657-
return std::vector<ProtocolConformance *>(result.begin(), result.end());
5658-
}
5659-
56605653
void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
56615654
auto *const dc = idc->getAsGenericContext();
56625655

@@ -5672,9 +5665,7 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
56725665
const auto defaultAccess = nominal->getFormalAccess();
56735666

56745667
// Check each of the conformances associated with this context.
5675-
auto conformances =
5676-
evaluateOrDefault(dc->getASTContext().evaluator,
5677-
LookupAllConformancesInContextRequest{idc}, {});
5668+
auto conformances = idc->getLocalConformances();
56785669

56795670
// The conformance checker bundle that checks all conformances in the context.
56805671
auto &Context = dc->getASTContext();

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,7 @@ static Type inferResultBuilderType(ValueDecl *decl) {
274274
auto addConformanceMatches = [&matches](ValueDecl *lookupDecl) {
275275
DeclContext *dc = lookupDecl->getDeclContext();
276276
auto idc = cast<IterableDeclContext>(dc->getAsDecl());
277-
auto conformances = evaluateOrDefault(
278-
dc->getASTContext().evaluator,
279-
LookupAllConformancesInContextRequest{idc}, { });
277+
auto conformances = idc->getLocalConformances();
280278

281279
for (auto conformance : conformances) {
282280
auto protocol = conformance->getProtocol();

0 commit comments

Comments
 (0)