mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Diagnose modules with circular dependencies (#16075)
This can't arise from a clean build, but it can happen if you have products lingering in a search path and then either rebuild one of the modules in the cycle, or change the search paths. The way this is implemented is for each module to track whether its imports have all been resolved. If, when loading a module, one of its dependencies hasn't resolved all of its imports yet, then we know there's a cycle. This doesn't produce the best diagnostics, but it's hard to get into this state in the first place, so that's probably okay. https://bugs.swift.org/browse/SR-7483
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "swift/Strings.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/DiagnosticsSema.h"
|
||||
#include "swift/Basic/Defer.h"
|
||||
#include "swift/Basic/STLExtras.h"
|
||||
#include "swift/Basic/SourceManager.h"
|
||||
#include "swift/Basic/Version.h"
|
||||
@@ -316,6 +317,25 @@ FileUnit *SerializedModuleLoader::loadAST(
|
||||
break;
|
||||
}
|
||||
|
||||
case serialization::Status::CircularDependency: {
|
||||
auto circularDependencyIter =
|
||||
llvm::find_if(loadedModuleFile->getDependencies(),
|
||||
[](const ModuleFile::Dependency &next) {
|
||||
return !next.Import.second->hasResolvedImports();
|
||||
});
|
||||
assert(circularDependencyIter != loadedModuleFile->getDependencies().end()
|
||||
&& "circular dependency reported, but no module with unresolved "
|
||||
"imports found");
|
||||
|
||||
// FIXME: We should include the path of the circularity as well, but that's
|
||||
// hard because we're discovering this /while/ resolving imports, which
|
||||
// means the problematic modules haven't been recorded yet.
|
||||
Ctx.Diags.diagnose(*diagLoc, diag::serialization_circular_dependency,
|
||||
circularDependencyIter->getPrettyPrintedPath(),
|
||||
M.getName());
|
||||
break;
|
||||
}
|
||||
|
||||
case serialization::Status::MissingShadowedModule: {
|
||||
Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_shadowed_module,
|
||||
M.getName());
|
||||
@@ -434,6 +454,7 @@ ModuleDecl *SerializedModuleLoader::loadModule(SourceLoc importLoc,
|
||||
|
||||
auto M = ModuleDecl::create(moduleID.first, Ctx);
|
||||
Ctx.LoadedModules[moduleID.first] = M;
|
||||
SWIFT_DEFER { M->setHasResolvedImports(); };
|
||||
|
||||
if (!loadAST(*M, moduleID.second, std::move(moduleInputBuffer),
|
||||
std::move(moduleDocInputBuffer), isFramework)) {
|
||||
|
||||
Reference in New Issue
Block a user