Skip to content

Commit 9d9d3e2

Browse files
[ScanDependencies] Do not count optional dependencies when not needed
If a testable module is loaded from a non-testable import, ignore its optional dependencies because the consumer should not use them. This matches the behavior of the implicit build or the behavior how forwarding module is created. (cherry picked from commit 77fefe9)
1 parent 9c65afa commit 9d9d3e2

File tree

3 files changed

+15
-20
lines changed

3 files changed

+15
-20
lines changed

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
174174
static BinaryModuleImports
175175
getImportsOfModule(const ModuleFileSharedCore &loadedModule,
176176
ModuleLoadingBehavior transitiveBehavior,
177-
StringRef packageName);
177+
StringRef packageName, bool isTestableImport);
178178

179179
/// Load the module file into a buffer and also collect its module name.
180180
static std::unique_ptr<llvm::MemoryBuffer>

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ std::error_code SerializedModuleLoaderBase::openModuleFile(
395395
SerializedModuleLoaderBase::BinaryModuleImports
396396
SerializedModuleLoaderBase::getImportsOfModule(
397397
const ModuleFileSharedCore &loadedModuleFile,
398-
ModuleLoadingBehavior transitiveBehavior, StringRef packageName) {
398+
ModuleLoadingBehavior transitiveBehavior, StringRef packageName,
399+
bool isTestableImport) {
399400
llvm::StringSet<> importedModuleNames;
400401
std::string importedHeader = "";
401402
for (const auto &dependency : loadedModuleFile.getDependencies()) {
@@ -410,8 +411,7 @@ SerializedModuleLoaderBase::getImportsOfModule(
410411
loadedModuleFile.getTransitiveLoadingBehavior(
411412
dependency,
412413
/*debuggerMode*/ false,
413-
/*isPartialModule*/ false, packageName,
414-
loadedModuleFile.isTestable());
414+
/*isPartialModule*/ false, packageName, isTestableImport);
415415
if (dependencyTransitiveBehavior > transitiveBehavior)
416416
continue;
417417

@@ -454,13 +454,6 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
454454
modulePath.str());
455455
return std::make_error_code(std::errc::no_such_file_or_directory);
456456
}
457-
458-
if (loadedModuleFile->isTestable() && !isTestableImport) {
459-
if (Ctx.LangOpts.EnableModuleLoadingRemarks)
460-
Ctx.Diags.diagnose(SourceLoc(), diag::skip_module_testable,
461-
modulePath.str());
462-
return std::make_error_code(std::errc::no_such_file_or_directory);
463-
}
464457
}
465458

466459
// Some transitive dependencies of binary modules are not required to be
@@ -471,12 +464,12 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
471464
// optional.
472465
auto binaryModuleImports =
473466
getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Required,
474-
Ctx.LangOpts.PackageName);
467+
Ctx.LangOpts.PackageName, isTestableImport);
475468

476469
// Lookup optional imports of this module also
477470
auto binaryModuleOptionalImports =
478471
getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Optional,
479-
Ctx.LangOpts.PackageName);
472+
Ctx.LangOpts.PackageName, isTestableImport);
480473

481474
auto importedModuleSet = binaryModuleImports.moduleImports;
482475
std::vector<std::string> importedModuleNames;

test/ScanDependencies/testable-dependencies.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@
1616
// RUN: -emit-module-interface-path %t/regular/A.swiftinterface -enable-library-evolution -I %t/internal \
1717
// RUN: %t/A.swift
1818

19-
/// Import testable build, should use interface.
19+
/// Import testable build, should use binary but no extra dependencies.
2020
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name Test %t/main.swift \
2121
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
22-
// RUN: -o %t/deps1.json -I %t/testable -swift-version 5 -Rmodule-loading 2>&1 | %FileCheck %s --check-prefix DIAG
23-
// DIAG: remark: skip swiftmodule built with '-enable-testing'
22+
// RUN: -o %t/deps1.json -I %t/testable -swift-version 5 -Rmodule-loading
2423
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps1.json Test directDependencies | %FileCheck %s --check-prefix TEST1
25-
// TEST1: "swift": "A"
24+
// TEST1: "swiftPrebuiltExternal": "A"
2625
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps1.json A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty
2726
// EMPTY-NOT: B
2827

@@ -56,12 +55,15 @@
5655
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \
5756
// RUN: -o %t/deps5.json -I %t/regular -swift-version 5 -Rmodule-loading
5857

59-
/// Regular import a testable module with no interface, this is a dependency scanning error.
58+
/// Regular import a testable module with no interface, don't load optional dependencies.
6059
// RUN: rm %t/testable/A.swiftinterface
6160
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/main.swift \
6261
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \
63-
// RUN: -o %t/deps6.json -I %t/testable -swift-version 5 -Rmodule-loading 2>&1 | %FileCheck %s --check-prefix ERROR
64-
// ERROR: error: Unable to find module dependency: 'A'
62+
// RUN: -o %t/deps6.json -I %t/testable -swift-version 5 -Rmodule-loading
63+
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps6.json Test directDependencies | %FileCheck %s --check-prefix TEST6
64+
// TEST6: "swiftPrebuiltExternal": "A"
65+
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps6.json swiftPrebuiltExternal:A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty
66+
6567

6668
//--- main.swift
6769
import A

0 commit comments

Comments
 (0)