Skip to content

Commit 842b909

Browse files
authored
Merge pull request #39139 from artemcm/DoNotBuildOnCanImport
Do not build Swift interface files into binary modules when performing a `canImport` query.
2 parents 7ab6554 + 1b7d555 commit 842b909

File tree

9 files changed

+50
-22
lines changed

9 files changed

+50
-22
lines changed

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
139139
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
140140
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
141141
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
142-
bool &isFramework, bool &isSystemModule) override;
142+
bool skipBuildingInterface, bool &isFramework,
143+
bool &isSystemModule) override;
143144

144145
std::error_code findModuleFilesInDirectory(
145146
ImportPath::Element ModuleID,
@@ -148,7 +149,7 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
148149
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
149150
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
150151
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
151-
bool IsFramework) override;
152+
bool skipBuildingInterface, bool IsFramework) override;
152153

153154
bool canImportModule(ImportPath::Element mID, llvm::VersionTuple version,
154155
bool underlyingVersion) override;
@@ -400,7 +401,7 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
400401
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
401402
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
402403
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
403-
bool IsFramework) override;
404+
bool skipBuildingInterface, bool IsFramework) override;
404405

405406
bool isCached(StringRef DepPath) override;
406407
public:

include/swift/Serialization/ModuleDependencyScanner.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace swift {
5555
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
5656
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
5757
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
58-
bool IsFramework) override;
58+
bool skipBuildingInterface, bool IsFramework) override;
5959

6060
virtual void collectVisibleTopLevelModuleNames(
6161
SmallVectorImpl<Identifier> &names) const override {
@@ -117,7 +117,7 @@ namespace swift {
117117
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
118118
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
119119
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
120-
bool IsFramework) override;
120+
bool skipBuildingInterface, bool IsFramework) override;
121121

122122
static bool classof(const ModuleDependencyScanner *MDS) {
123123
return MDS->getKind() == MDS_placeholder;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
7777
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
7878
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
7979
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
80-
bool &isFramework, bool &isSystemModule);
80+
bool skipBuildingInterface, bool &isFramework, bool &isSystemModule);
8181

8282
/// Attempts to search the provided directory for a loadable serialized
8383
/// .swiftmodule with the provided `ModuleFilename`. Subclasses must
@@ -98,7 +98,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
9898
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
9999
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
100100
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
101-
bool IsFramework) = 0;
101+
bool skipBuildingInterface, bool IsFramework) = 0;
102102

103103
std::error_code
104104
openModuleFile(
@@ -220,7 +220,7 @@ class ImplicitSerializedModuleLoader : public SerializedModuleLoaderBase {
220220
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
221221
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
222222
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
223-
bool IsFramework) override;
223+
bool skipBuildingInterface, bool IsFramework) override;
224224

225225
bool maybeDiagnoseTargetMismatch(
226226
SourceLoc sourceLocation,
@@ -272,7 +272,7 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
272272
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
273273
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
274274
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
275-
bool IsFramework) override;
275+
bool skipBuildingInterface, bool IsFramework) override;
276276

277277
bool maybeDiagnoseTargetMismatch(
278278
SourceLoc sourceLocation,

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
10831083
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
10841084
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
10851085
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
1086-
bool IsFramework) {
1086+
bool skipBuildingInterface, bool IsFramework) {
10871087

10881088
// If running in OnlySerialized mode, ModuleInterfaceLoader
10891089
// should not have been constructed at all.
@@ -1111,6 +1111,16 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
11111111
InPath = PrivateInPath;
11121112
}
11131113

1114+
// If we've been told to skip building interfaces, we are done here and do
1115+
// not need to have the module actually built. For example, if we are
1116+
// currently answering a `canImport` query, it is enough to have found
1117+
// the interface.
1118+
if (skipBuildingInterface) {
1119+
if (ModuleInterfacePath)
1120+
*ModuleInterfacePath = InPath;
1121+
return std::error_code();
1122+
}
1123+
11141124
// Create an instance of the Impl to do the heavy lifting.
11151125
auto ModuleName = ModuleID.Item.str();
11161126
ModuleInterfaceLoaderImpl Impl(
@@ -1711,7 +1721,7 @@ bool ExplicitSwiftModuleLoader::findModule(ImportPath::Element ModuleID,
17111721
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
17121722
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
17131723
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
1714-
bool &IsFramework, bool &IsSystemModule) {
1724+
bool skipBuildingInterface, bool &IsFramework, bool &IsSystemModule) {
17151725
StringRef moduleName = ModuleID.Item.str();
17161726
auto it = Impl.ExplicitModuleMap.find(moduleName);
17171727
// If no explicit module path is given matches the name, return with an
@@ -1783,7 +1793,7 @@ std::error_code ExplicitSwiftModuleLoader::findModuleFilesInDirectory(
17831793
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
17841794
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
17851795
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
1786-
bool IsFramework) {
1796+
bool skipBuildingInterface, bool IsFramework) {
17871797
llvm_unreachable("Not supported in the Explicit Swift Module Loader.");
17881798
return std::make_error_code(std::errc::not_supported);
17891799
}

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ std::error_code ModuleDependencyScanner::findModuleFilesInDirectory(
3232
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
3333
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
3434
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
35-
bool IsFramework) {
35+
bool skipBuildingInterface, bool IsFramework) {
3636
using namespace llvm::sys;
3737

3838
auto &fs = *Ctx.SourceMgr.getFileSystem();
@@ -77,7 +77,7 @@ std::error_code PlaceholderSwiftModuleScanner::findModuleFilesInDirectory(
7777
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
7878
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
7979
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
80-
bool IsFramework) {
80+
bool skipBuildingInterface, bool IsFramework) {
8181
StringRef moduleName = ModuleID.Item.str();
8282
auto it = PlaceholderDependencyModuleMap.find(moduleName);
8383
// If no placeholder module stub path is given matches the name, return with an

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ std::error_code ImplicitSerializedModuleLoader::findModuleFilesInDirectory(
423423
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
424424
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
425425
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
426-
bool IsFramework) {
426+
bool skipBuildingInterface, bool IsFramework) {
427427
assert(((ModuleBuffer && ModuleDocBuffer) ||
428428
(!ModuleBuffer && !ModuleDocBuffer)) &&
429429
"Module and Module Doc buffer must both be initialized or NULL");
@@ -516,7 +516,7 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
516516
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
517517
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
518518
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
519-
bool &isFramework, bool &isSystemModule) {
519+
bool skipBuildingInterface, bool &isFramework, bool &isSystemModule) {
520520
SmallString<32> moduleName(moduleID.Item.str());
521521
SerializedModuleBaseName genericBaseName(moduleName);
522522

@@ -554,6 +554,7 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
554554
moduleInterfacePath,
555555
moduleBuffer, moduleDocBuffer,
556556
moduleSourceInfoBuffer,
557+
skipBuildingInterface,
557558
IsFramework);
558559
if (!result) {
559560
return true;
@@ -611,7 +612,8 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
611612

612613
auto result = findModuleFilesInDirectory(
613614
moduleID, absoluteBaseName, moduleInterfacePath,
614-
moduleBuffer, moduleDocBuffer, moduleSourceInfoBuffer, isFramework);
615+
moduleBuffer, moduleDocBuffer, moduleSourceInfoBuffer,
616+
skipBuildingInterface, isFramework);
615617
if (!result)
616618
return true;
617619
else if (result == std::errc::not_supported)
@@ -1067,7 +1069,8 @@ bool SerializedModuleLoaderBase::canImportModule(
10671069

10681070
auto found = findModule(mID, unusedModuleInterfacePath, unusedModuleBuffer,
10691071
unusedModuleDocBuffer, unusedModuleSourceInfoBuffer,
1070-
isFramework, isSystemModule);
1072+
/* skipBuildingInterface */ true, isFramework,
1073+
isSystemModule);
10711074
// If we cannot find the module, don't continue.
10721075
if (!found)
10731076
return false;
@@ -1083,7 +1086,7 @@ bool SerializedModuleLoaderBase::canImportModule(
10831086
}
10841087
// If failing to extract the user version from the interface file, try the binary
10851088
// format, if present.
1086-
if (currentVersion.empty() && unusedModuleBuffer) {
1089+
if (currentVersion.empty() && *unusedModuleBuffer) {
10871090
auto metaData =
10881091
serialization::validateSerializedAST((*unusedModuleBuffer)->getBuffer());
10891092
currentVersion = metaData.userModuleVersion;
@@ -1137,7 +1140,7 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
11371140
// Look on disk.
11381141
if (!findModule(moduleID, &moduleInterfacePath, &moduleInputBuffer,
11391142
&moduleDocInputBuffer, &moduleSourceInfoInputBuffer,
1140-
isFramework, isSystemModule)) {
1143+
/* skipBuildingInterface */ false, isFramework, isSystemModule)) {
11411144
return nullptr;
11421145
}
11431146

@@ -1251,7 +1254,7 @@ std::error_code MemoryBufferSerializedModuleLoader::findModuleFilesInDirectory(
12511254
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
12521255
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
12531256
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
1254-
bool IsFramework) {
1257+
bool skipBuildingInterface, bool IsFramework) {
12551258
// This is a soft error instead of an llvm_unreachable because this API is
12561259
// primarily used by LLDB which makes it more likely that unwitting changes to
12571260
// the Swift compiler accidentally break the contract.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name Foo
3+
import Swift
4+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -c -primary-file %s -Rmodule-interface-rebuild -I %S/Inputs/Swift/
2+
3+
#if canImport(Foo)
4+
print("Can indeed import Foo!")
5+
#else
6+
print("Cannot import Foo!")
7+
#endif
8+
9+
// CHECK-NOT: rebuilding module 'Foo' from interface

unittests/FrontendTool/ModuleLoadingTests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ class ModuleInterfaceLoaderTest : public testing::Test {
128128
loader->findModuleFilesInDirectory({moduleName, SourceLoc()},
129129
SerializedModuleBaseName(tempDir, SerializedModuleBaseName("Library")),
130130
/*ModuleInterfacePath*/nullptr,
131-
&moduleBuffer, &moduleDocBuffer, &moduleSourceInfoBuffer, /*IsFramework*/false);
131+
&moduleBuffer, &moduleDocBuffer, &moduleSourceInfoBuffer,
132+
/*skipBuildingInterface*/ false, /*IsFramework*/false);
132133
ASSERT_FALSE(error);
133134
ASSERT_FALSE(diags.hadAnyError());
134135

0 commit comments

Comments
 (0)