Skip to content

Commit 7fb4480

Browse files
committed
Remove DependencyScope
1 parent 3dd74c1 commit 7fb4480

File tree

8 files changed

+37
-123
lines changed

8 files changed

+37
-123
lines changed

include/swift/AST/EvaluatorDependencies.h

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/AnyRequest.h"
2222
#include "swift/AST/AttrKind.h"
2323
#include "swift/AST/SourceFile.h"
24+
#include "swift/Basic/NullablePtr.h"
2425
#include "llvm/ADT/PointerIntPair.h"
2526

2627
namespace swift {
@@ -32,48 +33,13 @@ namespace detail {
3233
template <typename...> using void_t = void;
3334
} // namespace detail
3435

35-
/// The "scope" of a dependency edge tracked by the evaluator.
36-
///
37-
/// Dependency scopes come in two flavors: cascading and private. A private
38-
/// edge captures dependencies discovered in contexts that are not visible to
39-
/// to other files. For example, a conformance to a private protocol, or the use
40-
/// of any names inside of a function body. A cascading edge, by contrast,
41-
/// captures dependencies discovered in the remaining visible contexts. These
42-
/// are types with at least \c internal visibility, names defined or used
43-
/// outside of function bodies with at least \c internal visibility, etc. A
44-
/// dependency that has cascading scope is so-named because upon traversing the
45-
/// edge, a reader such as the driver should continue transitively evaluating
46-
/// further dependency edges.
47-
///
48-
/// A cascading edge is always conservatively correct to produce, but it comes
49-
/// at the cost of increased resources spent (and possibly even wasted!) during
50-
/// incremental compilation. A private edge, by contrast, is more efficient for
51-
/// incremental compilation but it is harder to safely use.
52-
///
53-
/// To ensure that these edges are registered consistently with the correct
54-
/// scopes, requests that act as the source of dependency edges are required
55-
/// to specify a \c DependencyScope under which all evaluated sub-requests will
56-
/// register their dependency edges. In this way, \c DependencyScope values
57-
/// form a stack-like structure and are pushed and popped by the evaluator
58-
/// during the course of request evaluation.
59-
///
60-
/// When determining the kind of scope a request should use, always err on the
61-
/// side of a cascading scope unless there is absolute proof any discovered
62-
/// dependencies will be private. Inner requests may also defensively choose to
63-
/// flip the dependency scope from private to cascading in the name of safety.
64-
enum class DependencyScope : bool {
65-
Private = false,
66-
Cascading = true,
67-
};
68-
69-
// A \c DependencySource is currently defined to be a parent source file and
70-
// an associated dependency scope.
36+
// A \c DependencySource is currently defined to be a parent source file.
7137
//
7238
// The \c SourceFile instance is an artifact of the current dependency system,
7339
// and should be scrapped if possible. It currently encodes the idea that
7440
// edges in the incremental dependency graph invalidate entire files instead
7541
// of individual contexts.
76-
using DependencySource = llvm::PointerIntPair<SourceFile *, 1, DependencyScope>;
42+
using DependencySource = swift::NullablePtr<SourceFile>;
7743

7844
struct DependencyRecorder;
7945

@@ -306,31 +272,21 @@ struct DependencyRecorder {
306272
ReferenceEnumerator f) const ;
307273

308274
public:
309-
/// Returns the scope of the current active scope.
310-
///
311-
/// If there is no active scope, the result always cascades.
312-
evaluator::DependencyScope getActiveSourceScope() const {
313-
if (dependencySources.empty()) {
314-
return evaluator::DependencyScope::Cascading;
315-
}
316-
return dependencySources.back().getInt();
317-
}
318-
319275
/// Returns the active dependency's source file, or \c nullptr if no
320276
/// dependency source is active.
321277
///
322278
/// The use of this accessor is strongly discouraged, as it implies that a
323279
/// dependency sink is seeking to filter out names based on the files they
324280
/// come from. Existing callers are being migrated to more reasonable ways
325281
/// of judging the relevancy of a dependency.
326-
SourceFile *getActiveDependencySourceOrNull() const {
282+
evaluator::DependencySource getActiveDependencySourceOrNull() const {
327283
if (dependencySources.empty())
328284
return nullptr;
329285
switch (mode) {
330286
case Mode::LegacyCascadingDependencies:
331-
return dependencySources.back().getPointer();
287+
return dependencySources.back();
332288
case Mode::DirectDependencies:
333-
return dependencySources.front().getPointer();
289+
return dependencySources.front();
334290
}
335291
}
336292

@@ -350,7 +306,7 @@ struct DependencyRecorder {
350306
auto Source = Req.readDependencySource(coll);
351307
// If there is no source to introduce, bail. This can occur if
352308
// a request originates in the context of a module.
353-
if (!Source.getPointer()) {
309+
if (Source.isNull()) {
354310
return;
355311
}
356312
coll.dependencySources.emplace_back(Source);
@@ -370,7 +326,7 @@ struct DependencyRecorder {
370326
bool isActiveSourceCascading() const {
371327
switch (mode) {
372328
case Mode::LegacyCascadingDependencies:
373-
return getActiveSourceScope() == evaluator::DependencyScope::Cascading;
329+
return false;
374330
case Mode::DirectDependencies:
375331
return false;
376332
}

lib/AST/ASTScopeLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ Optional<bool> PatternEntryInitializerScope::resolveIsCascadingUseForThisScope(
585585
// initializing stored property of a type
586586
auto *const patternDeclContext = decl->getDeclContext();
587587
if (patternDeclContext->isTypeContext())
588-
return isCascadingUseAccordingTo(PBI->getParent());
588+
return false;
589589

590590
// initializing global or local
591591
if (PBI)

lib/AST/Evaluator.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,7 @@ void Evaluator::dumpDependenciesGraphviz() const {
381381

382382
void evaluator::DependencyRecorder::realize(
383383
const DependencyCollector::Reference &ref) {
384-
auto *source = getActiveDependencySourceOrNull();
385-
assert(source && "cannot realize dependency without associated file!");
384+
auto *source = getActiveDependencySourceOrNull().get();
386385
if (!source->isPrimary()) {
387386
return;
388387
}
@@ -429,8 +428,8 @@ void evaluator::DependencyRecorder::record(
429428
const llvm::SetVector<swift::ActiveRequest> &stack,
430429
llvm::function_ref<void(DependencyCollector &)> rec) {
431430
assert(!isRecording && "Probably not a good idea to allow nested recording");
432-
auto *source = getActiveDependencySourceOrNull();
433-
if (!source || !source->isPrimary()) {
431+
auto source = getActiveDependencySourceOrNull();
432+
if (source.isNull() || !source.get()->isPrimary()) {
434433
return;
435434
}
436435

@@ -450,12 +449,12 @@ void evaluator::DependencyRecorder::replay(
450449
const swift::ActiveRequest &req) {
451450
assert(!isRecording && "Probably not a good idea to allow nested recording");
452451

453-
auto *source = getActiveDependencySourceOrNull();
452+
auto source = getActiveDependencySourceOrNull();
454453
if (mode == Mode::LegacyCascadingDependencies) {
455454
return;
456455
}
457456

458-
if (!source || !source->isPrimary()) {
457+
if (source.isNull() || !source.get()->isPrimary()) {
459458
return;
460459
}
461460

lib/AST/NameLookupRequests.cpp

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,8 @@ evaluator::DependencySource InheritedProtocolsRequest::readDependencySource(
9696
// type conforms to Hashable which itself looks up Equatable during
9797
// qualified lookup.
9898
if (!PD->getParentSourceFile())
99-
return { nullptr, e.getActiveSourceScope() };
100-
return {
101-
e.getActiveDependencySourceOrNull(),
102-
DependencyScope::Private,
103-
};
99+
return nullptr;
100+
return e.getActiveDependencySourceOrNull();
104101
}
105102

106103
void InheritedProtocolsRequest::writeDependencySink(
@@ -184,7 +181,7 @@ void ExtendedNominalRequest::writeDependencySink(
184181
auto *SF = std::get<0>(getStorage())->getParentSourceFile();
185182
if (!SF)
186183
return;
187-
if (SF != tracker.getRecorder().getActiveDependencySourceOrNull())
184+
if (SF != tracker.getRecorder().getActiveDependencySourceOrNull().getPtrOrNull())
188185
return;
189186
tracker.addPotentialMember(value);
190187
}
@@ -209,14 +206,7 @@ void GetDestructorRequest::cacheResult(DestructorDecl *value) const {
209206

210207
evaluator::DependencySource GetDestructorRequest::readDependencySource(
211208
const evaluator::DependencyRecorder &eval) const {
212-
// Looking up the deinitializer currently always occurs in a private
213-
// scope because it is impossible to reference 'deinit' in user code, and a
214-
// valid 'deinit' declaration cannot occur outside of the
215-
// definition of a type.
216-
return {
217-
eval.getActiveDependencySourceOrNull(),
218-
evaluator::DependencyScope::Private
219-
};
209+
return eval.getActiveDependencySourceOrNull();
220210
}
221211

222212
//----------------------------------------------------------------------------//
@@ -371,7 +361,7 @@ swift::extractNearestSourceLoc(const LookupConformanceDescriptor &desc) {
371361
evaluator::DependencySource ModuleQualifiedLookupRequest::readDependencySource(
372362
const evaluator::DependencyRecorder &eval) const {
373363
auto *DC = std::get<0>(getStorage());
374-
return { DC->getParentSourceFile(), evaluator::DependencyScope::Private };
364+
return DC->getParentSourceFile();
375365
}
376366

377367
void ModuleQualifiedLookupRequest::writeDependencySink(
@@ -403,13 +393,13 @@ void LookupConformanceInModuleRequest::writeDependencySink(
403393
if (!Adoptee)
404394
return;
405395

406-
auto *source = reqTracker.getRecorder().getActiveDependencySourceOrNull();
407-
if (!source)
396+
auto source = reqTracker.getRecorder().getActiveDependencySourceOrNull();
397+
if (source.isNull())
408398
return;
409399

410400
// Decline to record conformances defined outside of the active module.
411401
auto *conformance = lookupResult.getConcrete();
412-
if (source->getParentModule() !=
402+
if (source.get()->getParentModule() !=
413403
conformance->getDeclContext()->getParentModule())
414404
return;
415405
reqTracker.addPotentialMember(Adoptee);
@@ -421,12 +411,7 @@ void LookupConformanceInModuleRequest::writeDependencySink(
421411

422412
evaluator::DependencySource UnqualifiedLookupRequest::readDependencySource(
423413
const evaluator::DependencyRecorder &) const {
424-
auto &desc = std::get<0>(getStorage());
425-
// FIXME(Evaluator Incremental Dependencies): This maintains compatibility
426-
// with the existing scheme, but the existing scheme is totally ad-hoc. We
427-
// should remove this flag and ensure that non-cascading qualified lookups
428-
// occur in the right contexts instead.
429-
return {desc.DC->getParentSourceFile(), evaluator::DependencyScope::Cascading};
414+
return std::get<0>(getStorage()).DC->getParentSourceFile();
430415
}
431416

432417
void UnqualifiedLookupRequest::writeDependencySink(
@@ -441,11 +426,8 @@ void UnqualifiedLookupRequest::writeDependencySink(
441426

442427
evaluator::DependencySource QualifiedLookupRequest::readDependencySource(
443428
const evaluator::DependencyRecorder &) const {
444-
auto *dc = std::get<0>(getStorage());
445-
return {
446-
dyn_cast<SourceFile>(dc->getModuleScopeContext()),
447-
evaluator::DependencyScope::Private
448-
};
429+
auto *DC = std::get<0>(getStorage())->getModuleScopeContext();
430+
return dyn_cast<SourceFile>(DC);
449431
}
450432

451433
// Define request evaluation functions for each of the name lookup requests.

lib/AST/TypeCheckRequests.cpp

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,7 @@ void SuperclassTypeRequest::cacheResult(Type value) const {
159159

160160
evaluator::DependencySource SuperclassTypeRequest::readDependencySource(
161161
const evaluator::DependencyRecorder &e) const {
162-
const auto access = std::get<0>(getStorage())->getFormalAccess();
163-
return {
164-
e.getActiveDependencySourceOrNull(),
165-
evaluator::DependencyScope::Private,
166-
};
162+
return e.getActiveDependencySourceOrNull();
167163
}
168164

169165
void SuperclassTypeRequest::writeDependencySink(
@@ -1285,12 +1281,8 @@ void CheckRedeclarationRequest::cacheResult(evaluator::SideEffect) const {
12851281

12861282
evaluator::DependencySource CheckRedeclarationRequest::readDependencySource(
12871283
const evaluator::DependencyRecorder &eval) const {
1288-
auto *current = std::get<0>(getStorage());
1289-
auto *currentDC = current->getDeclContext();
1290-
return {
1291-
currentDC->getParentSourceFile(),
1292-
evaluator::DependencyScope::Private,
1293-
};
1284+
auto *currentDC = std::get<0>(getStorage())->getDeclContext();
1285+
return currentDC->getParentSourceFile();
12941286
}
12951287

12961288
void CheckRedeclarationRequest::writeDependencySink(
@@ -1320,16 +1312,7 @@ void CheckRedeclarationRequest::writeDependencySink(
13201312
evaluator::DependencySource
13211313
LookupAllConformancesInContextRequest::readDependencySource(
13221314
const evaluator::DependencyRecorder &collector) const {
1323-
const auto *nominal = std::get<0>(getStorage())
1324-
->getAsGenericContext()
1325-
->getSelfNominalTypeDecl();
1326-
if (!nominal) {
1327-
return {collector.getActiveDependencySourceOrNull(),
1328-
evaluator::DependencyScope::Cascading};
1329-
}
1330-
1331-
return {collector.getActiveDependencySourceOrNull(),
1332-
evaluator::DependencyScope::Private};
1315+
return collector.getActiveDependencySourceOrNull();
13331316
}
13341317

13351318
void LookupAllConformancesInContextRequest::writeDependencySink(
@@ -1369,7 +1352,7 @@ void ResolveTypeEraserTypeRequest::cacheResult(Type value) const {
13691352

13701353
evaluator::DependencySource TypeCheckSourceFileRequest::readDependencySource(
13711354
const evaluator::DependencyRecorder &e) const {
1372-
return {std::get<0>(getStorage()), evaluator::DependencyScope::Cascading};
1355+
return std::get<0>(getStorage());
13731356
}
13741357

13751358
Optional<evaluator::SideEffect>
@@ -1429,12 +1412,7 @@ void TypeCheckFunctionBodyRequest::cacheResult(BraceStmt *body) const {
14291412
evaluator::DependencySource
14301413
TypeCheckFunctionBodyRequest::readDependencySource(
14311414
const evaluator::DependencyRecorder &e) const {
1432-
// We're going under a function body scope, unconditionally flip the scope
1433-
// to private.
1434-
return {
1435-
std::get<0>(getStorage())->getParentSourceFile(),
1436-
evaluator::DependencyScope::Private
1437-
};
1415+
return std::get<0>(getStorage())->getParentSourceFile();
14381416
}
14391417

14401418
//----------------------------------------------------------------------------//

lib/IRGen/IRGenRequests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ evaluator::DependencySource IRGenRequest::readDependencySource(
102102

103103
// We don't track dependencies in whole-module mode.
104104
if (auto *mod = desc.Ctx.dyn_cast<ModuleDecl *>()) {
105-
return {nullptr, e.getActiveSourceScope()};
105+
return nullptr;
106106
}
107107

108108
auto *primary = desc.Ctx.get<FileUnit *>();
109-
return {dyn_cast<SourceFile>(primary), evaluator::DependencyScope::Cascading};
109+
return dyn_cast<SourceFile>(primary);
110110
}
111111

112112
// Define request evaluation functions for each of the IRGen requests.

lib/Parse/ParseRequests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
186186

187187
evaluator::DependencySource ParseSourceFileRequest::readDependencySource(
188188
const evaluator::DependencyRecorder &e) const {
189-
return {std::get<0>(getStorage()), evaluator::DependencyScope::Cascading};
189+
return std::get<0>(getStorage());
190190
}
191191

192192
Optional<SourceFileParsingResult>
@@ -229,7 +229,7 @@ void swift::simple_display(llvm::raw_ostream &out,
229229
evaluator::DependencySource
230230
CodeCompletionSecondPassRequest::readDependencySource(
231231
const evaluator::DependencyRecorder &e) const {
232-
return {std::get<0>(getStorage()), e.getActiveSourceScope()};
232+
return std::get<0>(getStorage());
233233
}
234234

235235
// Define request evaluation functions for each of the type checker requests.

lib/SILGen/SILGenRequests.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,11 @@ evaluator::DependencySource ASTLoweringRequest::readDependencySource(
5252

5353
// We don't track dependencies in whole-module mode.
5454
if (auto *mod = desc.context.dyn_cast<ModuleDecl *>()) {
55-
return {nullptr, e.getActiveSourceScope()};
55+
return nullptr;
5656
}
5757

5858
// If we have a single source file, it's the source of dependencies.
59-
auto *unit = desc.context.get<FileUnit *>();
60-
return {dyn_cast<SourceFile>(unit), evaluator::DependencyScope::Cascading};
59+
return dyn_cast<SourceFile>(desc.context.get<FileUnit *>());
6160
}
6261

6362
ArrayRef<FileUnit *> ASTLoweringDescriptor::getFilesToEmit() const {

0 commit comments

Comments
 (0)