Skip to content

Commit 09c15c3

Browse files
authored
Merge pull request #21730 from slavapestov/protocol-generic-signature-cleanup
Protocol generic signature cleanup
2 parents 1e27f21 + 033321f commit 09c15c3

File tree

8 files changed

+64
-44
lines changed

8 files changed

+64
-44
lines changed

lib/AST/Decl.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -745,13 +745,8 @@ GenericSignature *GenericContext::getGenericSignature() const {
745745

746746
// The signature of a Protocol is trivial (Self: TheProtocol) so let's compute
747747
// it.
748-
if (auto PD = dyn_cast<ProtocolDecl>(this)) {
749-
const_cast<ProtocolDecl *>(PD)->createGenericParamsIfMissing();
750-
auto self = PD->getSelfInterfaceType()->castTo<GenericTypeParamType>();
751-
auto req =
752-
Requirement(RequirementKind::Conformance, self, PD->getDeclaredType());
753-
return GenericSignature::get({self}, {req});
754-
}
748+
if (auto PD = dyn_cast<ProtocolDecl>(this))
749+
return getGenericEnvironment()->getGenericSignature();
755750

756751
return nullptr;
757752
}
@@ -765,6 +760,21 @@ GenericEnvironment *GenericContext::getGenericEnvironment() const {
765760
if (GenericSigOrEnv.dyn_cast<GenericSignature *>())
766761
return getLazyGenericEnvironmentSlow();
767762

763+
// The signature of a Protocol is trivial (Self: TheProtocol) so let's compute
764+
// it.
765+
if (auto PD = dyn_cast<ProtocolDecl>(this)) {
766+
const_cast<ProtocolDecl *>(PD)->createGenericParamsIfMissing();
767+
auto self = PD->getSelfInterfaceType()->castTo<GenericTypeParamType>();
768+
auto req =
769+
Requirement(RequirementKind::Conformance, self, PD->getDeclaredType());
770+
auto *genericSig = GenericSignature::get({self}, {req});
771+
772+
// Save it for next time.
773+
const_cast<GenericContext *>(this)
774+
->setGenericEnvironment(genericSig->createGenericEnvironment());
775+
return getGenericEnvironment();
776+
}
777+
768778
return nullptr;
769779
}
770780

lib/ClangImporter/ImportDecl.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4407,9 +4407,6 @@ namespace {
44074407
if (!result->isRequirementSignatureComputed())
44084408
result->computeRequirementSignature();
44094409

4410-
auto *env = Impl.buildGenericEnvironment(result->getGenericParams(), dc);
4411-
result->setGenericEnvironment(env);
4412-
44134410
result->setMemberLoader(&Impl, 0);
44144411

44154412
// Add the protocol decl to ExternalDefinitions so that IRGen can emit

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,6 +3704,7 @@ bool swift::isExtensionApplied(DeclContext &DC, Type BaseTy,
37043704
return true;
37053705

37063706
TypeChecker *TC = &createTypeChecker(DC.getASTContext());
3707+
TC->validateExtension(const_cast<ExtensionDecl *>(ED));
37073708

37083709
ConstraintSystemOptions Options;
37093710
ConstraintSystem CS(*TC, &DC, Options);

lib/Sema/ConstraintSystem.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,11 @@ Type ConstraintSystem::openType(Type type, OpenedTypeMap &replacements) {
583583
if (auto genericParam = type->getAs<GenericTypeParamType>()) {
584584
auto known = replacements.find(
585585
cast<GenericTypeParamType>(genericParam->getCanonicalType()));
586-
assert(known != replacements.end());
586+
// FIXME: This should be an assert, however protocol generic signatures
587+
// drop outer generic parameters.
588+
// assert(known != replacements.end());
589+
if (known == replacements.end())
590+
return ErrorType::get(TC.Context);
587591
return known->second;
588592
}
589593

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,10 @@ static void doGlobalExtensionLookup(Type BaseType,
192192
extension))
193193
continue;
194194

195-
bool validatedExtension = false;
196195
for (auto Member : extension->getMembers()) {
197196
if (auto VD = dyn_cast<ValueDecl>(Member))
198-
if (isDeclVisibleInLookupMode(VD, LS, CurrDC, TypeResolver)) {
199-
// Resolve the extension, if we haven't done so already.
200-
if (!validatedExtension && TypeResolver) {
201-
TypeResolver->resolveExtension(extension);
202-
validatedExtension = true;
203-
}
204-
197+
if (isDeclVisibleInLookupMode(VD, LS, CurrDC, TypeResolver))
205198
FoundDecls.push_back(VD);
206-
}
207199
}
208200
}
209201

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4193,13 +4193,6 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
41934193
return;
41944194
proto->computeType();
41954195

4196-
auto *gp = proto->getGenericParams();
4197-
gp->setDepth(proto->getGenericContextDepth());
4198-
4199-
for (auto ATD : proto->getAssociatedTypeMembers()) {
4200-
validateDeclForNameLookup(ATD);
4201-
}
4202-
42034196
// Compute the requirement signature later to avoid circularity.
42044197
DelayedRequirementSignatures.insert(proto);
42054198

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,40 @@ GenericEnvironment *TypeChecker::checkGenericEnvironment(
754754
}
755755

756756
void TypeChecker::validateGenericTypeSignature(GenericTypeDecl *typeDecl) {
757+
if (auto *proto = dyn_cast<ProtocolDecl>(typeDecl)) {
758+
// Compute the requirement signature first.
759+
if (!proto->isRequirementSignatureComputed())
760+
proto->computeRequirementSignature();
761+
762+
// The generic signature and environment is created lazily by
763+
// GenericContext::getGenericSignature(), so there is nothing we
764+
// need to do.
765+
766+
// Debugging of the generic signature builder and generic signature
767+
// generation.
768+
if (Context.LangOpts.DebugGenericSignatures) {
769+
auto *sig = proto->getGenericSignature();
770+
771+
proto->printContext(llvm::errs());
772+
llvm::errs() << "\n";
773+
llvm::errs() << "Generic signature: ";
774+
sig->print(llvm::errs());
775+
llvm::errs() << "\n";
776+
llvm::errs() << "Canonical generic signature: ";
777+
sig->getCanonicalSignature()->print(llvm::errs());
778+
llvm::errs() << "\n";
779+
}
780+
781+
return;
782+
}
783+
757784
assert(!typeDecl->getGenericEnvironment());
758785

786+
// We don't go down this path for protocols; instead, the generic signature
787+
// is simple enough that GenericContext::getGenericSignature() can build it
788+
// directly.
789+
assert(!isa<ProtocolDecl>(typeDecl));
790+
759791
auto *gp = typeDecl->getGenericParams();
760792
auto *dc = typeDecl->getDeclContext();
761793

@@ -767,13 +799,6 @@ void TypeChecker::validateGenericTypeSignature(GenericTypeDecl *typeDecl) {
767799

768800
gp->setDepth(typeDecl->getGenericContextDepth());
769801

770-
// For a protocol, compute the requirement signature first. It will be used
771-
// by clients of the protocol.
772-
if (auto proto = dyn_cast<ProtocolDecl>(typeDecl)) {
773-
if (!proto->isRequirementSignatureComputed())
774-
proto->computeRequirementSignature();
775-
}
776-
777802
auto *env = checkGenericEnvironment(gp, dc,
778803
dc->getGenericSignatureOfContext(),
779804
/*allowConcreteGenericParams=*/false,

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,21 +3185,19 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
31853185

31863186
auto *aliasDecl = dyn_cast<TypeAliasDecl>(member);
31873187
if (aliasDecl) {
3188+
if (aliasDecl->getGenericParams()) {
3189+
return UnboundGenericType::get(
3190+
aliasDecl, baseTy,
3191+
aliasDecl->getASTContext());
3192+
}
3193+
31883194
// FIXME: If this is a protocol typealias and we haven't built the
31893195
// protocol's generic environment yet, do so now, to ensure the
31903196
// typealias's underlying type has fully resolved dependent
31913197
// member types.
31923198
if (auto *protoDecl = dyn_cast<ProtocolDecl>(aliasDecl->getDeclContext())) {
3193-
if (protoDecl->getGenericEnvironment() == nullptr) {
3194-
ASTContext &ctx = protoDecl->getASTContext();
3195-
ctx.getLazyResolver()->resolveProtocolEnvironment(protoDecl);
3196-
}
3197-
}
3198-
3199-
if (aliasDecl->getGenericParams()) {
3200-
return UnboundGenericType::get(
3201-
aliasDecl, baseTy,
3202-
aliasDecl->getASTContext());
3199+
ASTContext &ctx = protoDecl->getASTContext();
3200+
ctx.getLazyResolver()->resolveProtocolEnvironment(protoDecl);
32033201
}
32043202
}
32053203

0 commit comments

Comments
 (0)