Skip to content

Commit eb40cc5

Browse files
Merge pull request #73087 from cachemeifyoucan/eng/PR-testable-import-deps-optional
[ScanDependencies] Do not count optional dependencies when not needed
2 parents 532a7de + 77fefe9 commit eb40cc5

File tree

4 files changed

+21
-34
lines changed

4 files changed

+21
-34
lines changed

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
163163
}
164164

165165
/// Scan the given serialized module file to determine dependencies.
166-
llvm::ErrorOr<ModuleDependencyInfo> scanModuleFile(Twine modulePath,
167-
bool isFramework,
168-
bool isTestableImport,
169-
bool hasInterface);
166+
llvm::ErrorOr<ModuleDependencyInfo>
167+
scanModuleFile(Twine modulePath, bool isFramework, bool isTestableImport);
170168

171169
struct BinaryModuleImports {
172170
llvm::StringSet<> moduleImports;
@@ -176,7 +174,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
176174
static BinaryModuleImports
177175
getImportsOfModule(const ModuleFileSharedCore &loadedModule,
178176
ModuleLoadingBehavior transitiveBehavior,
179-
StringRef packageName);
177+
StringRef packageName, bool isTestableImport);
180178

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

lib/Serialization/ScanningLoaders.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ std::error_code SwiftModuleScanner::findModuleFilesInDirectory(
5757
if (fs.exists(ModPath)) {
5858
// The module file will be loaded directly.
5959
auto dependencies =
60-
scanModuleFile(ModPath, IsFramework, isTestableDependencyLookup,
61-
/*hasInterface=*/false);
60+
scanModuleFile(ModPath, IsFramework, isTestableDependencyLookup);
6261
if (dependencies) {
6362
this->dependencies = std::move(dependencies.get());
6463
return std::error_code();
@@ -160,9 +159,8 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
160159
!Ctx.SearchPathOpts.NoScannerModuleValidation) {
161160
assert(compiledCandidates.size() == 1 &&
162161
"Should only have 1 candidate module");
163-
auto BinaryDep =
164-
scanModuleFile(compiledCandidates[0], isFramework,
165-
isTestableImport, /*hasInterface=*/true);
162+
auto BinaryDep = scanModuleFile(compiledCandidates[0], isFramework,
163+
isTestableImport);
166164
if (BinaryDep) {
167165
Result = *BinaryDep;
168166
return std::error_code();

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 6 additions & 17 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

@@ -431,8 +431,7 @@ SerializedModuleLoaderBase::getImportsOfModule(
431431

432432
llvm::ErrorOr<ModuleDependencyInfo>
433433
SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
434-
bool isTestableImport,
435-
bool hasInterface) {
434+
bool isTestableImport) {
436435
const std::string moduleDocPath;
437436
const std::string sourceInfoPath;
438437

@@ -455,16 +454,6 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
455454
modulePath.str());
456455
return std::make_error_code(std::errc::no_such_file_or_directory);
457456
}
458-
459-
// If the module file has interface file and not testable imported, don't
460-
// import the testable module because it contains more interfaces than
461-
// needed and can pull in more dependencies.
462-
if (loadedModuleFile->isTestable() && !isTestableImport && hasInterface) {
463-
if (Ctx.LangOpts.EnableModuleLoadingRemarks)
464-
Ctx.Diags.diagnose(SourceLoc(), diag::skip_module_testable,
465-
modulePath.str());
466-
return std::make_error_code(std::errc::no_such_file_or_directory);
467-
}
468457
}
469458

470459
// Some transitive dependencies of binary modules are not required to be
@@ -475,12 +464,12 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
475464
// optional.
476465
auto binaryModuleImports =
477466
getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Required,
478-
Ctx.LangOpts.PackageName);
467+
Ctx.LangOpts.PackageName, isTestableImport);
479468

480469
// Lookup optional imports of this module also
481470
auto binaryModuleOptionalImports =
482471
getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Optional,
483-
Ctx.LangOpts.PackageName);
472+
Ctx.LangOpts.PackageName, isTestableImport);
484473

485474
auto importedModuleSet = binaryModuleImports.moduleImports;
486475
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, will try to import binary module but fail to look up the dependency.
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: 'B'
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)