Skip to content

Commit 851f640

Browse files
committed
Lift implementation-only import checking into a request
This diagnostic logic is currently called from `finishTypeChecking`, however it doesn't need to be delayed until after all the source files have been type-checked, only after they have all had their imports resolved. It can therefore be lifted into a request that operates on a ModuleDecl, and be called from TypeCheckSourceFileRequest. Being a request will ensure that the pass is only run once across the module. Eventually we'll probably want to re-do import resolution so that it operates on an entire module. At that point, we'll want to look at integrating this diagnostic logic into it.
1 parent 5121349 commit 851f640

File tree

6 files changed

+47
-20
lines changed

6 files changed

+47
-20
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,6 +2430,32 @@ class ResolveTypeRequest
24302430
void simple_display(llvm::raw_ostream &out, const TypeResolution *resolution);
24312431
SourceLoc extractNearestSourceLoc(const TypeRepr *repr);
24322432

2433+
/// Checks to see if any of the imports in a module use `@_implementationOnly`
2434+
/// in one file and not in another.
2435+
///
2436+
/// Like redeclaration checking, but for imports.
2437+
///
2438+
/// This is a request purely to ensure that we don't need to perform the same
2439+
/// checking for each file we resolve imports for.
2440+
/// FIXME: Once import resolution operates at module-level, this checking can
2441+
/// integrated into it.
2442+
class CheckInconsistentImplementationOnlyImportsRequest
2443+
: public SimpleRequest<CheckInconsistentImplementationOnlyImportsRequest,
2444+
evaluator::SideEffect(ModuleDecl *),
2445+
RequestFlags::Cached> {
2446+
public:
2447+
using SimpleRequest::SimpleRequest;
2448+
2449+
private:
2450+
friend SimpleRequest;
2451+
2452+
evaluator::SideEffect evaluate(Evaluator &evaluator, ModuleDecl *mod) const;
2453+
2454+
public:
2455+
// Cached.
2456+
bool isCached() const { return true; }
2457+
};
2458+
24332459
// Allow AnyValue to compare two Type values, even though Type doesn't
24342460
// support ==.
24352461
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ SWIFT_REQUEST(TypeChecker, AttachedPropertyWrappersRequest,
2929
NoLocationInfo)
3030
SWIFT_REQUEST(TypeChecker, CallerSideDefaultArgExprRequest,
3131
Expr *(DefaultArgumentExpr *), SeparatelyCached, NoLocationInfo)
32+
SWIFT_REQUEST(TypeChecker, CheckInconsistentImplementationOnlyImportsRequest,
33+
evaluator::SideEffect(ModuleDecl *), Cached, NoLocationInfo)
3234
SWIFT_REQUEST(TypeChecker, CheckRedeclarationRequest,
3335
evaluator::SideEffect(ValueDecl *),
3436
Uncached, NoLocationInfo)

include/swift/Subsystems.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,6 @@ namespace swift {
152152
/// emitted.
153153
void performWholeModuleTypeChecking(SourceFile &SF);
154154

155-
/// Checks to see if any of the imports in \p M use `@_implementationOnly` in
156-
/// one file and not in another.
157-
///
158-
/// Like redeclaration checking, but for imports. This isn't part of
159-
/// swift::performWholeModuleTypeChecking because it's linear in the number
160-
/// of declarations in the module.
161-
void checkInconsistentImplementationOnlyImports(ModuleDecl *M);
162-
163155
/// Recursively validate the specified type.
164156
///
165157
/// This is used when dealing with partial source files (e.g. SIL parsing,

lib/Frontend/Frontend.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,8 +897,6 @@ void CompilerInstance::finishTypeChecking() {
897897
performWholeModuleTypeChecking(SF);
898898
});
899899
}
900-
901-
checkInconsistentImplementationOnlyImports(MainModule);
902900
}
903901

904902
SourceFile *CompilerInstance::createSourceFileForMainModule(

lib/Sema/ImportResolution.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -674,18 +674,20 @@ void UnboundImport::diagnoseInvalidAttr(DeclAttrKind attrKind,
674674
attr->setInvalid();
675675
}
676676

677-
void swift::checkInconsistentImplementationOnlyImports(ModuleDecl *MainModule) {
677+
evaluator::SideEffect
678+
CheckInconsistentImplementationOnlyImportsRequest::evaluate(
679+
Evaluator &evaluator, ModuleDecl *mod) const {
678680
bool hasAnyImplementationOnlyImports =
679-
llvm::any_of(MainModule->getFiles(), [](const FileUnit *F) -> bool {
680-
auto *SF = dyn_cast<SourceFile>(F);
681-
return SF && SF->hasImplementationOnlyImports();
682-
});
681+
llvm::any_of(mod->getFiles(), [](const FileUnit *F) -> bool {
682+
auto *SF = dyn_cast<SourceFile>(F);
683+
return SF && SF->hasImplementationOnlyImports();
684+
});
683685
if (!hasAnyImplementationOnlyImports)
684-
return;
686+
return {};
685687

686-
auto diagnose = [MainModule](const ImportDecl *normalImport,
687-
const ImportDecl *implementationOnlyImport) {
688-
auto &diags = MainModule->getDiags();
688+
auto diagnose = [mod](const ImportDecl *normalImport,
689+
const ImportDecl *implementationOnlyImport) {
690+
auto &diags = mod->getDiags();
689691
{
690692
InFlightDiagnostic warning =
691693
diags.diagnose(normalImport, diag::warn_implementation_only_conflict,
@@ -706,7 +708,7 @@ void swift::checkInconsistentImplementationOnlyImports(ModuleDecl *MainModule) {
706708
llvm::DenseMap<ModuleDecl *, std::vector<const ImportDecl *>> normalImports;
707709
llvm::DenseMap<ModuleDecl *, const ImportDecl *> implementationOnlyImports;
708710

709-
for (const FileUnit *file : MainModule->getFiles()) {
711+
for (const FileUnit *file : mod->getFiles()) {
710712
auto *SF = dyn_cast<SourceFile>(file);
711713
if (!SF)
712714
continue;
@@ -750,6 +752,7 @@ void swift::checkInconsistentImplementationOnlyImports(ModuleDecl *MainModule) {
750752
normalImports[module].push_back(nextImport);
751753
}
752754
}
755+
return {};
753756
}
754757

755758
//===----------------------------------------------------------------------===//

lib/Sema/TypeChecker.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,12 @@ TypeCheckSourceFileRequest::evaluate(Evaluator &eval, SourceFile *SF) const {
351351
typeCheckDelayedFunctions(*SF);
352352
}
353353

354+
// Check to see if there's any inconsistent @_implementationOnly imports.
355+
evaluateOrDefault(
356+
Ctx.evaluator,
357+
CheckInconsistentImplementationOnlyImportsRequest{SF->getParentModule()},
358+
{});
359+
354360
// Checking that benefits from having the whole module available.
355361
if (!Ctx.TypeCheckerOpts.DelayWholeModuleChecking) {
356362
performWholeModuleTypeChecking(*SF);

0 commit comments

Comments
 (0)