[Dependency Scanning] Emit a note if a dependency cycle is between the source target and another Swift module with the same name

The note will point the user to where the "other" module with the same name is located and mention whether it is an SDK module. This is nice to have in various circumstances where developers attempt to define a module with the same name as a Swift module that already exists on their search paths, for example in the SDK.
This commit is contained in:
Artem Chikin
2025-07-01 13:09:23 -07:00
parent beb2b58d62
commit 0d3def55df
6 changed files with 134 additions and 25 deletions

View File

@@ -1868,28 +1868,6 @@ void ModuleDependencyScanner::diagnoseScannerFailure(
}
}
static std::string getModuleDefiningPath(const ModuleDependencyInfo &info) {
std::string path = "";
switch (info.getKind()) {
case swift::ModuleDependencyKind::SwiftInterface:
path = info.getAsSwiftInterfaceModule()->swiftInterfaceFile;
break;
case swift::ModuleDependencyKind::SwiftBinary:
path = info.getAsSwiftBinaryModule()->compiledModulePath;
break;
case swift::ModuleDependencyKind::Clang:
path = info.getAsClangModule()->moduleMapFile;
break;
case swift::ModuleDependencyKind::SwiftSource:
default:
llvm_unreachable("Unexpected dependency kind");
}
// Relative to the `module.modulemap` or `.swiftinterface` or `.swiftmodule`,
// the defininig path is the parent directory of the file.
return llvm::sys::path::parent_path(path).str();
}
std::optional<std::pair<ModuleDependencyID, std::string>>
ModuleDependencyScanner::attemptToFindResolvingSerializedSearchPath(
const ScannerImportStatementInfo &moduleImport,
@@ -1922,13 +1900,13 @@ ModuleDependencyScanner::attemptToFindResolvingSerializedSearchPath(
/* isTestableImport */ false);
if (!result.empty())
return std::make_pair(binaryDepID,
getModuleDefiningPath(result[0].second));
result[0].second.getModuleDefiningPath());
result = ScanningWorker->scanFilesystemForClangModuleDependency(
getModuleImportIdentifier(moduleImport.importIdentifier), {});
if (!result.empty())
return std::make_pair(binaryDepID,
getModuleDefiningPath(result[0].second));
return std::make_pair(
binaryDepID, result[0].second.getModuleDefiningPath());
return std::nullopt;
});
if (result)