mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Define Dependency Sinks
Convert most of the name lookup requests and a few other ancillary typechecking requests into dependency sinks. Some requests are also combined sinks and sources in order to emulate the current scheme, which performs scope changes based on lookup flags. This is generally undesirable, since it means those requests cannot immediately be generalized to a purely context-based scheme because they depend on some client-provided entropy source. In particular, the few callers that are providing the "known private" name lookup flag need to be converted to perform lookups in the appropriate private context. Clients that are passing "no known dependency" are currently considered universally incorrect and are outside the scope of the compatibility guarantees. This means that request-based dependency tracking registers strictly more edges than manual dependency tracking. It also means that once we fixup the clients that are passing "known private", we can completely remove these name lookup flags. Finally, some tests had to change to accomodate the new scheme. Currently, we go out of our way to register a dependency edge for extensions that declare protocol conformances. However, we were also asserting in at least one test that extensions without protocol conformances weren't registering dependency edges. This is blatantly incorrect and has been undone now that the request-based scheme is automatically registering this edge.
This commit is contained in:
@@ -1272,6 +1272,34 @@ OperatorType *LookupOperatorRequest<OperatorType>::evaluate(
|
||||
return result.hasValue() ? result.getValue() : nullptr;
|
||||
}
|
||||
|
||||
template <typename OperatorType>
|
||||
void LookupOperatorRequest<OperatorType>::writeDependencySink(
|
||||
Evaluator &evaluator, OperatorType *o) const {
|
||||
auto &desc = std::get<0>(this->getStorage());
|
||||
auto *FU = desc.fileOrModule.template get<FileUnit *>();
|
||||
auto shouldRegisterDependencyEdge = [&FU](OperatorType *o) -> bool {
|
||||
if (!o)
|
||||
return true;
|
||||
|
||||
auto *topLevelContext = o->getDeclContext()->getModuleScopeContext();
|
||||
return topLevelContext != FU;
|
||||
};
|
||||
|
||||
// FIXME(Evaluator Incremental Dependencies): This is all needlessly complex.
|
||||
// For one, it does not take into account the fact that precedence groups can
|
||||
// be shadowed, and so should be registered regardless of their defining
|
||||
// module. Second, lookups for operators within the file define a valid named
|
||||
// dependency just as much as lookups outside of the current source file.
|
||||
if (!shouldRegisterDependencyEdge(o)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *reqTracker = evaluator.getActiveDependencyTracker();
|
||||
if (!reqTracker)
|
||||
return;
|
||||
reqTracker->addTopLevelName(desc.name, desc.isCascading);
|
||||
}
|
||||
|
||||
#define LOOKUP_OPERATOR(Kind) \
|
||||
Kind##Decl *ModuleDecl::lookup##Kind(Identifier name, SourceLoc loc) { \
|
||||
auto result = \
|
||||
@@ -1281,7 +1309,9 @@ OperatorType *LookupOperatorRequest<OperatorType>::evaluate(
|
||||
} \
|
||||
template Kind##Decl * \
|
||||
LookupOperatorRequest<Kind##Decl>::evaluate(Evaluator &e, \
|
||||
OperatorLookupDescriptor d) const;
|
||||
OperatorLookupDescriptor) const; \
|
||||
template \
|
||||
void LookupOperatorRequest<Kind##Decl>::writeDependencySink(Evaluator &, Kind##Decl *) const; \
|
||||
|
||||
LOOKUP_OPERATOR(PrefixOperator)
|
||||
LOOKUP_OPERATOR(InfixOperator)
|
||||
|
||||
Reference in New Issue
Block a user