Skip to content

Commit 6556926

Browse files
committed
[AST] Switch ProtocolDecl::requiresClass() over to decl-based resolution.
Resolving whether a protocol is class-bound only requires declaration-based resolution (not the full type checker), so switch over to those APIs.
1 parent 971a6e3 commit 6556926

File tree

4 files changed

+76
-36
lines changed

4 files changed

+76
-36
lines changed

include/swift/AST/NameLookup.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,23 @@ void lookupInModule(ModuleDecl *module, ModuleDecl::AccessPathTy accessPath,
356356
/// "inherited" by the given declaration at a particular position in the
357357
/// list of "inherited" types.
358358
///
359-
/// Add anything we find to the
359+
/// Add anything we find to the \c result vector. If we come across the
360+
/// AnyObject type, set \c anyObject true.
360361
void getDirectlyInheritedNominalTypeDecls(
361362
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
362363
unsigned i,
363-
llvm::SmallVectorImpl<std::pair<SourceLoc, NominalTypeDecl *>> &result);
364+
llvm::SmallVectorImpl<std::pair<SourceLoc, NominalTypeDecl *>> &result,
365+
bool &anyObject);
364366

365367
/// Retrieve the set of nominal type declarations that are directly
366368
/// "inherited" by the given declaration, looking through typealiases
367369
/// and splitting out the components of compositions.
370+
///
371+
/// If we come across the AnyObject type, set \c anyObject true.
368372
SmallVector<std::pair<SourceLoc, NominalTypeDecl *>, 4>
369373
getDirectlyInheritedNominalTypeDecls(
370-
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl);
374+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
375+
bool &anyObject);
371376

372377
} // end namespace swift
373378

lib/AST/ConformanceLookupTable.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,9 @@ void ConformanceLookupTable::addInheritedProtocols(
490490
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
491491
ConformanceSource source) {
492492
// Find all of the protocols in the inheritance list.
493-
for (const auto &found : getDirectlyInheritedNominalTypeDecls(decl)) {
493+
bool anyObject = false;
494+
for (const auto &found :
495+
getDirectlyInheritedNominalTypeDecls(decl, anyObject)) {
494496
if (auto proto = dyn_cast<ProtocolDecl>(found.second))
495497
addProtocol(proto, found.first, source);
496498
}

lib/AST/Decl.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "swift/AST/LazyResolver.h"
3232
#include "swift/AST/ASTMangler.h"
3333
#include "swift/AST/Module.h"
34+
#include "swift/AST/NameLookup.h"
3435
#include "swift/AST/NameLookupRequests.h"
3536
#include "swift/AST/ParameterList.h"
3637
#include "swift/AST/Pattern.h"
@@ -3652,31 +3653,32 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
36523653
bool ProtocolDecl::requiresClassSlow() {
36533654
// Set this first to catch (invalid) circular inheritance.
36543655
Bits.ProtocolDecl.RequiresClassValid = true;
3656+
Bits.ProtocolDecl.RequiresClass = false;
36553657

36563658
// Quick check: @objc protocols require a class.
3657-
if (isObjC()) {
3658-
Bits.ProtocolDecl.RequiresClass = true;
3659-
return true;
3660-
}
3661-
3662-
// Otherwise, check if the inheritance clause contains a
3663-
// class-constrained existential.
3664-
//
3665-
// FIXME: Use the requirement signature if available.
3666-
Bits.ProtocolDecl.RequiresClass = false;
3667-
for (unsigned i : indices(getInherited())) {
3668-
Type type = getInheritedType(i);
3669-
assert(type && "Should have type checked inheritance clause by now");
3670-
if (type->isExistentialType()) {
3671-
auto layout = type->getExistentialLayout();
3672-
if (layout.requiresClass()) {
3673-
Bits.ProtocolDecl.RequiresClass = true;
3674-
return true;
3675-
}
3676-
}
3677-
if (type->getClassOrBoundGenericClass()) {
3678-
Bits.ProtocolDecl.RequiresClass = true;
3679-
return true;
3659+
if (isObjC())
3660+
return Bits.ProtocolDecl.RequiresClass = true;
3661+
3662+
// Determine the set of nominal types that this protocol inherits.
3663+
bool anyObject = false;
3664+
auto allInheritedNominals =
3665+
getDirectlyInheritedNominalTypeDecls(this, anyObject);
3666+
3667+
// Quick check: do we inherit AnyObject?
3668+
if (anyObject)
3669+
return Bits.ProtocolDecl.RequiresClass = true;
3670+
3671+
// Look through all of the inherited nominals for a superclass or a
3672+
// class-bound protocol.
3673+
for (const auto &found : allInheritedNominals) {
3674+
// Superclass bound.
3675+
if (isa<ClassDecl>(found.second))
3676+
return Bits.ProtocolDecl.RequiresClass = true;
3677+
3678+
// A protocol that might be class-constrained;
3679+
if (auto proto = dyn_cast<ProtocolDecl>(found.second)) {
3680+
if (proto->requiresClass())
3681+
return Bits.ProtocolDecl.RequiresClass = true;
36803682
}
36813683
}
36823684

lib/AST/NameLookup.cpp

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,7 +1957,8 @@ static TinyPtrVector<NominalTypeDecl *>
19571957
resolveTypeDeclsToNominal(Evaluator &evaluator,
19581958
ASTContext &ctx,
19591959
ArrayRef<TypeDecl *> typeDecls,
1960-
SmallVectorImpl<ModuleDecl *> &modulesFound) {
1960+
SmallVectorImpl<ModuleDecl *> &modulesFound,
1961+
bool &anyObject) {
19611962
TinyPtrVector<NominalTypeDecl *> nominalDecls;
19621963

19631964
for (auto typeDecl : typeDecls) {
@@ -1973,10 +1974,32 @@ resolveTypeDeclsToNominal(Evaluator &evaluator,
19731974
= evaluator(UnderlyingTypeDeclsReferencedRequest{typealias});
19741975
auto underlyingNominalReferences
19751976
= resolveTypeDeclsToNominal(evaluator, ctx, underlyingTypeReferences,
1976-
modulesFound);
1977+
modulesFound, anyObject);
19771978
nominalDecls.insert(nominalDecls.end(),
19781979
underlyingNominalReferences.begin(),
19791980
underlyingNominalReferences.end());
1981+
1982+
// Recognize Swift.AnyObject directly.
1983+
if (typealias->getName().is("AnyObject")) {
1984+
// TypeRepr version: Builtin.AnyObject
1985+
if (auto typeRepr = typealias->getUnderlyingTypeLoc().getTypeRepr()) {
1986+
if (auto compound = dyn_cast<CompoundIdentTypeRepr>(typeRepr)) {
1987+
auto components = compound->getComponents();
1988+
if (components.size() == 2 &&
1989+
components[0]->getIdentifier().is("Builtin") &&
1990+
components[1]->getIdentifier().is("AnyObject")) {
1991+
anyObject = true;
1992+
}
1993+
}
1994+
}
1995+
1996+
// Type version: an empty class-bound existential.
1997+
if (auto type = typealias->getUnderlyingTypeLoc().getType()) {
1998+
if (type->isAnyObject())
1999+
anyObject = true;
2000+
}
2001+
}
2002+
19802003
continue;
19812004
}
19822005

@@ -2018,8 +2041,10 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator,
20182041
// Look through the base types to find something on which we can perform
20192042
// qualified name lookup.
20202043
SmallVector<ModuleDecl *, 2> moduleBaseTypes;
2044+
bool anyObject = false;
20212045
auto nominalBaseTypes =
2022-
resolveTypeDeclsToNominal(evaluator, ctx, baseTypes, moduleBaseTypes);
2046+
resolveTypeDeclsToNominal(evaluator, ctx, baseTypes, moduleBaseTypes,
2047+
anyObject);
20232048

20242049
DirectlyReferencedTypeDecls result;
20252050
auto addResults = [&result](ArrayRef<ValueDecl *> found){
@@ -2241,9 +2266,10 @@ ClassDecl *SuperclassDeclRequest::evaluate(Evaluator &evaluator,
22412266

22422267
// Resolve those type declarations to nominal type declarations.
22432268
SmallVector<ModuleDecl *, 2> modulesFound;
2269+
bool anyObject = false;
22442270
auto inheritedNominalTypes
22452271
= resolveTypeDeclsToNominal(evaluator, subject->getASTContext(),
2246-
inheritedTypes, modulesFound);
2272+
inheritedTypes, modulesFound, anyObject);
22472273

22482274
// Look for a class declaration.
22492275
for (auto inheritedNominal : inheritedNominalTypes) {
@@ -2273,15 +2299,18 @@ NominalTypeDecl *ExtendedNominalRequest::evaluate(Evaluator &evaluator,
22732299

22742300
// Resolve those type declarations to nominal type declarations.
22752301
SmallVector<ModuleDecl *, 2> modulesFound;
2302+
bool anyObject = false;
22762303
auto nominalTypes
2277-
= resolveTypeDeclsToNominal(evaluator, ctx, referenced, modulesFound);
2304+
= resolveTypeDeclsToNominal(evaluator, ctx, referenced, modulesFound,
2305+
anyObject);
22782306
return nominalTypes.empty() ? nullptr : nominalTypes.front();
22792307
}
22802308

22812309
void swift::getDirectlyInheritedNominalTypeDecls(
22822310
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
22832311
unsigned i,
2284-
llvm::SmallVectorImpl<std::pair<SourceLoc, NominalTypeDecl *>> &result) {
2312+
llvm::SmallVectorImpl<std::pair<SourceLoc, NominalTypeDecl *>> &result,
2313+
bool &anyObject) {
22852314
auto typeDecl = decl.dyn_cast<TypeDecl *>();
22862315
auto extDecl = decl.dyn_cast<ExtensionDecl *>();
22872316

@@ -2294,7 +2323,8 @@ void swift::getDirectlyInheritedNominalTypeDecls(
22942323
// Resolve those type declarations to nominal type declarations.
22952324
SmallVector<ModuleDecl *, 2> modulesFound;
22962325
auto nominalTypes
2297-
= resolveTypeDeclsToNominal(ctx.evaluator, ctx, referenced, modulesFound);
2326+
= resolveTypeDeclsToNominal(ctx.evaluator, ctx, referenced, modulesFound,
2327+
anyObject);
22982328

22992329
// Dig out the source location
23002330
// FIXME: This is a hack. We need cooperation from
@@ -2313,7 +2343,8 @@ void swift::getDirectlyInheritedNominalTypeDecls(
23132343

23142344
SmallVector<std::pair<SourceLoc, NominalTypeDecl *>, 4>
23152345
swift::getDirectlyInheritedNominalTypeDecls(
2316-
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl) {
2346+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
2347+
bool &anyObject) {
23172348
auto typeDecl = decl.dyn_cast<TypeDecl *>();
23182349
auto extDecl = decl.dyn_cast<ExtensionDecl *>();
23192350

@@ -2322,7 +2353,7 @@ swift::getDirectlyInheritedNominalTypeDecls(
23222353
: extDecl->getInherited().size();
23232354
SmallVector<std::pair<SourceLoc, NominalTypeDecl *>, 4> result;
23242355
for (unsigned i : range(numInherited)) {
2325-
getDirectlyInheritedNominalTypeDecls(decl, i, result);
2356+
getDirectlyInheritedNominalTypeDecls(decl, i, result, anyObject);
23262357
}
23272358

23282359
return result;

0 commit comments

Comments
 (0)