Skip to content

[NFC] AST: Relocate some conformance lookup client methods from DeclContext to IterableDeclContext #31645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 32 additions & 35 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace swift {
class Expr;
class GenericParamList;
class LazyMemberLoader;
class GenericContext;
class GenericSignature;
class GenericTypeParamDecl;
class GenericTypeParamType;
Expand Down Expand Up @@ -566,41 +567,6 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
LLVM_READONLY
ASTContext &getASTContext() const;

/// Retrieve the set of protocols whose conformances will be
/// associated with this declaration context.
///
/// This function differs from \c getLocalConformances() in that it
/// returns protocol declarations, not protocol conformances, and
/// therefore does not require the protocol conformances to be
/// formed.
///
/// \param lookupKind The kind of lookup to perform.
///
/// FIXME: This likely makes more sense on IterableDeclContext or
/// something similar.
SmallVector<ProtocolDecl *, 2>
getLocalProtocols(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All) const;

/// Retrieve the set of protocol conformances associated with this
/// declaration context.
///
/// \param lookupKind The kind of lookup to perform.
///
/// FIXME: This likely makes more sense on IterableDeclContext or
/// something similar.
SmallVector<ProtocolConformance *, 2>
getLocalConformances(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All) const;

/// Retrieve diagnostics discovered while expanding conformances for this
/// declaration context. This operation then removes those diagnostics from
/// consideration, so subsequent calls to this function with the same
/// declaration context that have not had any new extensions bound
/// will see an empty array.
SmallVector<ConformanceDiagnostic, 4>
takeConformanceDiagnostics() const;

/// Retrieves a list of separately imported overlays which are shadowing
/// \p declaring. If any \p overlays are returned, qualified lookups into
/// \p declaring should be performed into \p overlays instead; since they
Expand Down Expand Up @@ -815,9 +781,40 @@ class IterableDeclContext {
/// valid).
bool wasDeserialized() const;

/// Retrieve the set of protocols whose conformances will be
/// associated with this declaration context.
///
/// This function differs from \c getLocalConformances() in that it
/// returns protocol declarations, not protocol conformances, and
/// therefore does not require the protocol conformances to be
/// formed.
///
/// \param lookupKind The kind of lookup to perform.
SmallVector<ProtocolDecl *, 2>
getLocalProtocols(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All) const;

/// Retrieve the set of protocol conformances associated with this
/// declaration context.
///
/// \param lookupKind The kind of lookup to perform.
SmallVector<ProtocolConformance *, 2>
getLocalConformances(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All) const;

/// Retrieve diagnostics discovered while expanding conformances for this
/// declaration context. This operation then removes those diagnostics from
/// consideration, so subsequent calls to this function with the same
/// declaration context that have not had any new extensions bound
/// will see an empty array.
SmallVector<ConformanceDiagnostic, 4> takeConformanceDiagnostics() const;

/// Return 'this' as a \c Decl.
const Decl *getDecl() const;

/// Return 'this' as a \c GenericContext.
const GenericContext *getAsGenericContext() const;

/// Get the DeclID this Decl was deserialized from.
serialization::DeclID getDeclID() const {
assert(wasDeserialized());
Expand Down
5 changes: 3 additions & 2 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -2259,7 +2259,8 @@ void simple_display(llvm::raw_ostream &out, ConformanceLookupKind kind);
/// must also be reported so it can be checked as well.
class LookupAllConformancesInContextRequest
: public SimpleRequest<LookupAllConformancesInContextRequest,
ProtocolConformanceLookupResult(const DeclContext *),
ProtocolConformanceLookupResult(
const IterableDeclContext *),
RequestFlags::Uncached |
RequestFlags::DependencySink |
RequestFlags::DependencySource> {
Expand All @@ -2271,7 +2272,7 @@ class LookupAllConformancesInContextRequest

// Evaluation.
ProtocolConformanceLookupResult
evaluate(Evaluator &evaluator, const DeclContext *DC) const;
evaluate(Evaluator &evaluator, const IterableDeclContext *IDC) const;

public:
// Incremental dependencies
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ SWIFT_REQUEST(TypeChecker, ScopedImportLookupRequest,
SWIFT_REQUEST(TypeChecker, ClosureHasExplicitResultRequest,
bool(ClosureExpr *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, LookupAllConformancesInContextRequest,
ProtocolConformanceLookupResult(const DeclContext *),
ProtocolConformanceLookupResult(const IterableDeclContext *),
Uncached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, SimpleDidSetRequest,
bool(AccessorDecl *), Cached, NoLocationInfo)
18 changes: 14 additions & 4 deletions lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,16 @@ IterableDeclContext::getDecl() const {
llvm_unreachable("Unhandled IterableDeclContextKind in switch.");
}

const GenericContext *IterableDeclContext::getAsGenericContext() const {
switch (getIterableContextKind()) {
case IterableDeclContextKind::NominalTypeDecl:
return cast<NominalTypeDecl>(this);
case IterableDeclContextKind::ExtensionDecl:
return cast<ExtensionDecl>(this);
}
llvm_unreachable("Unhandled IterableDeclContextKind in switch.");
}

ASTContext &IterableDeclContext::getASTContext() const {
return getDecl()->getASTContext();
}
Expand Down Expand Up @@ -853,7 +863,7 @@ bool IterableDeclContext::hasUnparsedMembers() const {
if (AddedParsedMembers)
return false;

if (!getDecl()->getDeclContext()->getParentSourceFile()) {
if (!getAsGenericContext()->getParentSourceFile()) {
// There will never be any parsed members to add, so set the flag to say
// we are done so we can short-circuit next time.
const_cast<IterableDeclContext *>(this)->AddedParsedMembers = 1;
Expand All @@ -873,7 +883,7 @@ void IterableDeclContext::loadAllMembers() const {
ASTContext &ctx = getASTContext();

// For contexts within a source file, get the list of parsed members.
if (getDecl()->getDeclContext()->getParentSourceFile()) {
if (getAsGenericContext()->getParentSourceFile()) {
// Retrieve the parsed members. Even if we've already added the parsed
// members to this context, this call is important for recording the
// dependency edge.
Expand Down Expand Up @@ -911,7 +921,7 @@ void IterableDeclContext::loadAllMembers() const {
}

bool IterableDeclContext::wasDeserialized() const {
const DeclContext *DC = cast<DeclContext>(getDecl());
const DeclContext *DC = getAsGenericContext();
if (auto F = dyn_cast<FileUnit>(DC->getModuleScopeContext())) {
return F->getKind() == FileUnitKind::SerializedAST;
}
Expand Down Expand Up @@ -943,7 +953,7 @@ IterableDeclContext::castDeclToIterableDeclContext(const Decl *D) {

Optional<std::string> IterableDeclContext::getBodyFingerprint() const {
// Only makes sense for contexts in a source file
if (!getDecl()->getDeclContext()->getParentSourceFile())
if (!getAsGenericContext()->getParentSourceFile())
return None;
auto mutableThis = const_cast<IterableDeclContext *>(this);
return evaluateOrDefault(getASTContext().evaluator,
Expand Down
27 changes: 16 additions & 11 deletions lib/AST/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,11 +1319,12 @@ NominalTypeDecl::getSatisfiedProtocolRequirementsForMember(
}

SmallVector<ProtocolDecl *, 2>
DeclContext::getLocalProtocols(ConformanceLookupKind lookupKind) const {
IterableDeclContext::getLocalProtocols(ConformanceLookupKind lookupKind) const {
SmallVector<ProtocolDecl *, 2> result;

// Dig out the nominal type.
NominalTypeDecl *nominal = getSelfNominalTypeDecl();
const auto dc = getAsGenericContext();
const auto nominal = dc->getSelfNominalTypeDecl();
if (!nominal) {
return result;
}
Expand All @@ -1332,7 +1333,7 @@ DeclContext::getLocalProtocols(ConformanceLookupKind lookupKind) const {
nominal->prepareConformanceTable();
nominal->ConformanceTable->lookupConformances(
nominal,
const_cast<DeclContext *>(this),
const_cast<GenericContext *>(dc),
lookupKind,
&result,
nullptr,
Expand All @@ -1342,11 +1343,13 @@ DeclContext::getLocalProtocols(ConformanceLookupKind lookupKind) const {
}

SmallVector<ProtocolConformance *, 2>
DeclContext::getLocalConformances(ConformanceLookupKind lookupKind) const {
IterableDeclContext::getLocalConformances(ConformanceLookupKind lookupKind)
const {
SmallVector<ProtocolConformance *, 2> result;

// Dig out the nominal type.
NominalTypeDecl *nominal = getSelfNominalTypeDecl();
const auto dc = getAsGenericContext();
const auto nominal = dc->getSelfNominalTypeDecl();
if (!nominal) {
return result;
}
Expand All @@ -1365,7 +1368,7 @@ DeclContext::getLocalConformances(ConformanceLookupKind lookupKind) const {
nominal->prepareConformanceTable();
nominal->ConformanceTable->lookupConformances(
nominal,
const_cast<DeclContext *>(this),
const_cast<GenericContext *>(dc),
lookupKind,
nullptr,
&result,
Expand All @@ -1375,25 +1378,27 @@ DeclContext::getLocalConformances(ConformanceLookupKind lookupKind) const {
}

SmallVector<ConformanceDiagnostic, 4>
DeclContext::takeConformanceDiagnostics() const {
IterableDeclContext::takeConformanceDiagnostics() const {
SmallVector<ConformanceDiagnostic, 4> result;

// Dig out the nominal type.
NominalTypeDecl *nominal = getSelfNominalTypeDecl();
const auto dc = getAsGenericContext();
const auto nominal = dc->getSelfNominalTypeDecl();

if (!nominal) {
return { };
return result;
}

// Protocols are not subject to the checks for supersession.
if (isa<ProtocolDecl>(nominal)) {
return { };
return result;
}

// Update to record all potential conformances.
nominal->prepareConformanceTable();
nominal->ConformanceTable->lookupConformances(
nominal,
const_cast<DeclContext *>(this),
const_cast<GenericContext *>(dc),
ConformanceLookupKind::All,
nullptr,
nullptr,
Expand Down
20 changes: 8 additions & 12 deletions lib/AST/TypeCheckRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1385,20 +1385,16 @@ void CheckRedeclarationRequest::writeDependencySink(
evaluator::DependencySource
LookupAllConformancesInContextRequest::readDependencySource(
const evaluator::DependencyCollector &collector) const {
auto *dc = std::get<0>(getStorage());
AccessLevel defaultAccess;
if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
const NominalTypeDecl *nominal = ext->getExtendedNominal();
if (!nominal) {
return {collector.getActiveDependencySourceOrNull(),
evaluator::DependencyScope::Cascading};
}
defaultAccess = nominal->getFormalAccess();
} else {
defaultAccess = cast<NominalTypeDecl>(dc)->getFormalAccess();
const auto *nominal = std::get<0>(getStorage())
->getAsGenericContext()
->getSelfNominalTypeDecl();
if (!nominal) {
return {collector.getActiveDependencySourceOrNull(),
evaluator::DependencyScope::Cascading};
}

return {collector.getActiveDependencySourceOrNull(),
evaluator::getScopeForAccessLevel(defaultAccess)};
evaluator::getScopeForAccessLevel(nominal->getFormalAccess())};
}

void LookupAllConformancesInContextRequest::writeDependencySink(
Expand Down
7 changes: 4 additions & 3 deletions lib/IDE/Refactoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2730,7 +2730,8 @@ bool RefactoringActionConvertToTernaryExpr::performChange() {
/// these stubs should be filled.
class FillProtocolStubContext {

std::vector<ValueDecl*> getUnsatisfiedRequirements(const DeclContext *DC);
std::vector<ValueDecl*>
getUnsatisfiedRequirements(const IterableDeclContext *IDC);

/// Context in which the content should be filled; this could be either a
/// nominal type declaraion or an extension declaration.
Expand Down Expand Up @@ -2801,12 +2802,12 @@ getContextFromCursorInfo(ResolvedCursorInfo CursorInfo) {
}

std::vector<ValueDecl*> FillProtocolStubContext::
getUnsatisfiedRequirements(const DeclContext *DC) {
getUnsatisfiedRequirements(const IterableDeclContext *IDC) {
// The results to return.
std::vector<ValueDecl*> NonWitnessedReqs;

// For each conformance of the extended nominal.
for(ProtocolConformance *Con : DC->getLocalConformances()) {
for(ProtocolConformance *Con : IDC->getLocalConformances()) {

// Collect non-witnessed requirements.
Con->forEachNonWitnessedRequirement(
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/GenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,9 +1116,9 @@ namespace {

/// Gather protocol records for all of the explicitly-specified Objective-C
/// protocol conformances.
void visitConformances(DeclContext *dc) {
void visitConformances(const IterableDeclContext *idc) {
llvm::SmallSetVector<ProtocolDecl *, 2> protocols;
for (auto conformance : dc->getLocalConformances(
for (auto conformance : idc->getLocalConformances(
ConformanceLookupKind::OnlyExplicit)) {
ProtocolDecl *proto = conformance->getProtocol();
getObjCProtocols(proto, protocols);
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -913,9 +913,9 @@ IRGenModule::getConstantReferenceForProtocolDescriptor(ProtocolDecl *proto) {
LinkEntity::forProtocolDescriptor(proto));
}

void IRGenModule::addLazyConformances(DeclContext *dc) {
void IRGenModule::addLazyConformances(const IterableDeclContext *idc) {
for (const ProtocolConformance *conf :
dc->getLocalConformances(ConformanceLookupKind::All)) {
idc->getLocalConformances(ConformanceLookupKind::All)) {
IRGen.addLazyWitnessTable(conf);
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1586,8 +1586,9 @@ private: \
void addRuntimeResolvableType(GenericTypeDecl *nominal);
void maybeEmitOpaqueTypeDecl(OpaqueTypeDecl *opaque);

/// Add all conformances of the given \c DeclContext LazyWitnessTables.
void addLazyConformances(DeclContext *dc);
/// Add all conformances of the given \c IterableDeclContext
/// LazyWitnessTables.
void addLazyConformances(const IterableDeclContext *idc);

//--- Global context emission --------------------------------------------------
public:
Expand Down
7 changes: 4 additions & 3 deletions lib/Index/Index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,11 +777,12 @@ bool IndexSwiftASTWalker::visitImports(
}

bool IndexSwiftASTWalker::handleWitnesses(Decl *D, SmallVectorImpl<IndexedWitness> &explicitWitnesses) {
auto DC = dyn_cast<DeclContext>(D);
if (!DC)
const auto *const IDC = dyn_cast<IterableDeclContext>(D);
if (!IDC)
return true;

for (auto *conf : DC->getLocalConformances()) {
const auto DC = IDC->getAsGenericContext();
for (auto *conf : IDC->getLocalConformances()) {
if (conf->isInvalid())
continue;

Expand Down
2 changes: 1 addition & 1 deletion lib/Parse/ParseRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void swift::simple_display(llvm::raw_ostream &out,
FingerprintAndMembers
ParseMembersRequest::evaluate(Evaluator &evaluator,
IterableDeclContext *idc) const {
SourceFile &sf = *idc->getDecl()->getDeclContext()->getParentSourceFile();
SourceFile &sf = *idc->getAsGenericContext()->getParentSourceFile();
unsigned bufferID = *sf.getBufferID();

// Lexer diaganostics have been emitted during skipping, so we disable lexer's
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/DerivedConformanceEquatableHashable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1026,11 +1026,11 @@ getHashValueRequirement(ASTContext &C) {
}

static ProtocolConformance *
getHashableConformance(Decl *parentDecl) {
getHashableConformance(const Decl *parentDecl) {
ASTContext &C = parentDecl->getASTContext();
auto DC = cast<DeclContext>(parentDecl);
const auto IDC = cast<IterableDeclContext>(parentDecl);
auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable);
for (auto conformance: DC->getLocalConformances()) {
for (auto conformance: IDC->getLocalConformances()) {
if (conformance->getProtocol() == hashableProto) {
return conformance;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/LookupVisibleDecls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ static void
// wrappers.
static void
synthesizePropertyWrapperStorageWrapperProperties(IterableDeclContext *IDC) {
auto SF = IDC->getDecl()->getDeclContext()->getParentSourceFile();
auto SF = IDC->getAsGenericContext()->getParentSourceFile();
if (!SF || SF->Kind == SourceFileKind::Interface)
return;

Expand Down
Loading