Skip to content

Commit 1dc4797

Browse files
committed
Sema: Refactor conformance checking to use lookupQualified() instead of lookupMember()
TypeChecker::lookupMember() maps protocol requirements to witnesses, which we disable here by clearing NameLookupFlags::PerformConformanceCheck. Instead, let's call lookupQualified() directly, since lookupMember() doesn't add any value in this case.
1 parent c4725f6 commit 1dc4797

File tree

2 files changed

+62
-32
lines changed

2 files changed

+62
-32
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,16 +1105,25 @@ WitnessChecker::WitnessChecker(ASTContext &ctx, ProtocolDecl *proto,
11051105
void
11061106
WitnessChecker::lookupValueWitnessesViaImplementsAttr(
11071107
ValueDecl *req, SmallVector<ValueDecl *, 4> &witnesses) {
1108-
auto lookupOptions = defaultMemberTypeLookupOptions;
1109-
lookupOptions -= NameLookupFlags::PerformConformanceCheck;
1110-
lookupOptions |= NameLookupFlags::IncludeAttributeImplements;
1111-
auto candidates = TypeChecker::lookupMember(DC, Adoptee, req->createNameRef(),
1112-
lookupOptions);
1113-
for (auto candidate : candidates) {
1114-
if (witnessHasImplementsAttrForExactRequirement(candidate.getValueDecl(), req)) {
1115-
witnesses.push_back(candidate.getValueDecl());
1116-
}
1108+
1109+
auto name = req->createNameRef();
1110+
auto *nominal = Adoptee->getAnyNominal();
1111+
1112+
NLOptions subOptions = (NL_ProtocolMembers | NL_IncludeAttributeImplements);
1113+
1114+
nominal->synthesizeSemanticMembersIfNeeded(name.getFullName());
1115+
1116+
SmallVector<ValueDecl *, 4> lookupResults;
1117+
DC->lookupQualified(nominal, name, subOptions, lookupResults);
1118+
1119+
for (auto decl : lookupResults) {
1120+
if (!isa<ProtocolDecl>(decl->getDeclContext()))
1121+
if (witnessHasImplementsAttrForExactRequirement(decl, req))
1122+
witnesses.push_back(decl);
11171123
}
1124+
1125+
removeOverriddenDecls(witnesses);
1126+
removeShadowedDecls(witnesses, DC);
11181127
}
11191128

11201129
SmallVector<ValueDecl *, 4>
@@ -1147,23 +1156,34 @@ WitnessChecker::lookupValueWitnesses(ValueDecl *req, bool *ignoringNames) {
11471156
}
11481157
} else {
11491158
// Variable/function/subscript requirements.
1150-
auto lookupOptions = defaultMemberTypeLookupOptions;
1151-
lookupOptions -= NameLookupFlags::PerformConformanceCheck;
1152-
1153-
auto candidates = TypeChecker::lookupMember(DC, Adoptee, reqName,
1154-
lookupOptions);
1159+
auto *nominal = Adoptee->getAnyNominal();
1160+
nominal->synthesizeSemanticMembersIfNeeded(reqName.getFullName());
1161+
1162+
SmallVector<ValueDecl *, 4> lookupResults;
1163+
bool addedAny = false;
1164+
DC->lookupQualified(nominal, reqName, NL_ProtocolMembers, lookupResults);
1165+
for (auto *decl : lookupResults) {
1166+
if (!isa<ProtocolDecl>(decl->getDeclContext())) {
1167+
witnesses.push_back(decl);
1168+
addedAny = true;
1169+
}
1170+
};
11551171

11561172
// If we didn't find anything with the appropriate name, look
11571173
// again using only the base name.
1158-
if (candidates.empty() && ignoringNames) {
1159-
candidates = TypeChecker::lookupMember(DC, Adoptee, reqBaseName,
1160-
lookupOptions);
1174+
if (!addedAny && ignoringNames) {
1175+
lookupResults.clear();
1176+
DC->lookupQualified(nominal, reqBaseName, NL_ProtocolMembers, lookupResults);
1177+
for (auto *decl : lookupResults) {
1178+
if (!isa<ProtocolDecl>(decl->getDeclContext()))
1179+
witnesses.push_back(decl);
1180+
}
1181+
11611182
*ignoringNames = true;
11621183
}
11631184

1164-
for (auto candidate : candidates) {
1165-
witnesses.push_back(candidate.getValueDecl());
1166-
}
1185+
removeOverriddenDecls(witnesses);
1186+
removeShadowedDecls(witnesses, DC);
11671187
}
11681188

11691189
return witnesses;
@@ -5121,16 +5141,20 @@ diagnoseMissingAppendInterpolationMethod(NominalTypeDecl *typeDecl) {
51215141

51225142
static bool hasValidMethod(NominalTypeDecl *typeDecl,
51235143
SmallVectorImpl<InvalidMethod> &invalid) {
5124-
auto type = typeDecl->getDeclaredType();
5144+
NLOptions subOptions = NL_QualifiedDefault;
5145+
subOptions |= NL_ProtocolMembers;
5146+
51255147
DeclNameRef baseName(typeDecl->getASTContext().Id_appendInterpolation);
5126-
auto lookupOptions = defaultMemberTypeLookupOptions;
5127-
lookupOptions -= NameLookupFlags::PerformConformanceCheck;
51285148

5129-
for (auto resultEntry :
5130-
TypeChecker::lookupMember(typeDecl, type, baseName, lookupOptions)) {
5131-
auto method = dyn_cast<FuncDecl>(resultEntry.getValueDecl());
5149+
SmallVector<ValueDecl *, 4> lookupResults;
5150+
typeDecl->lookupQualified(typeDecl, baseName, subOptions, lookupResults);
5151+
for (auto decl : lookupResults) {
5152+
auto method = dyn_cast<FuncDecl>(decl);
51325153
if (!method) continue;
5133-
5154+
5155+
if (isa<ProtocolDecl>(method->getDeclContext()))
5156+
continue;
5157+
51345158
if (method->isStatic()) {
51355159
invalid.emplace_back(method, Reason::Static);
51365160
continue;

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -595,15 +595,21 @@ AssociatedTypeInference::inferTypeWitnessesViaAssociatedType(
595595
defaultName = DeclNameRef(getASTContext().getIdentifier(defaultNameStr));
596596
}
597597

598+
NLOptions subOptions = (NL_QualifiedDefault |
599+
NL_OnlyTypes |
600+
NL_ProtocolMembers);
601+
598602
// Look for types with the given default name that have appropriate
599603
// @_implements attributes.
604+
SmallVector<ValueDecl *, 4> lookupResults;
605+
dc->lookupQualified(adoptee->getAnyNominal(), defaultName,
606+
subOptions, lookupResults);
607+
600608
InferredAssociatedTypesByWitnesses result;
601-
auto lookupOptions = defaultMemberTypeLookupOptions;
602-
lookupOptions -= NameLookupFlags::PerformConformanceCheck;
603-
for (auto candidate :
604-
TypeChecker::lookupMember(dc, adoptee, defaultName, lookupOptions)) {
609+
610+
for (auto decl : lookupResults) {
605611
// We want type declarations.
606-
auto typeDecl = dyn_cast<TypeDecl>(candidate.getValueDecl());
612+
auto typeDecl = dyn_cast<TypeDecl>(decl);
607613
if (!typeDecl || isa<AssociatedTypeDecl>(typeDecl))
608614
continue;
609615

0 commit comments

Comments
 (0)