Skip to content

Commit 6a5f7fd

Browse files
authored
Merge pull request #37126 from beccadax/not-gonna-go-fast
2 parents db8b9d5 + 77117b0 commit 6a5f7fd

File tree

7 files changed

+83
-22
lines changed

7 files changed

+83
-22
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ WARNING(warning_module_shadowing_may_break_module_interface,none,
371371
/*shadowedModule=*/ModuleDecl *, /*interfaceModule*/ModuleDecl *))
372372
REMARK(rebuilding_module_from_interface,none,
373373
"rebuilding module '%0' from interface '%1'", (StringRef, StringRef))
374+
REMARK(rebuilding_stdlib_from_interface,none,
375+
"did not find a prebuilt standard library for target '%0' compatible "
376+
"with this Swift compiler; building it may take a few minutes, but it "
377+
"should only happen once for this combination of compiler and target",
378+
(StringRef))
374379
NOTE(sdk_version_pbm_version,none,
375380
"SDK build version is '%0'; prebuilt modules were "
376381
"built using SDK build version: '%1'", (StringRef, StringRef))

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -287,44 +287,45 @@ struct ModuleRebuildInfo {
287287

288288
/// Emits a diagnostic for all out-of-date compiled or forwarding modules
289289
/// encountered while trying to load a module.
290-
void diagnose(ASTContext &ctx, SourceLoc loc, StringRef moduleName,
291-
StringRef interfacePath, StringRef prebuiltCacheDir) {
292-
ctx.Diags.diagnose(loc, diag::rebuilding_module_from_interface,
293-
moduleName, interfacePath);
290+
template<typename... DiagArgs>
291+
void diagnose(ASTContext &ctx, DiagnosticEngine &diags,
292+
StringRef prebuiltCacheDir, SourceLoc loc,
293+
DiagArgs &&...diagArgs) {
294+
diags.diagnose(loc, std::forward<DiagArgs>(diagArgs)...);
294295
auto SDKVer = getSDKBuildVersion(ctx.SearchPathOpts.SDKPath);
295296
llvm::SmallString<64> buffer = prebuiltCacheDir;
296297
llvm::sys::path::append(buffer, "SystemVersion.plist");
297298
auto PBMVer = getSDKBuildVersionFromPlist(buffer.str());
298299
if (!SDKVer.empty() && !PBMVer.empty()) {
299300
// Remark the potential version difference.
300-
ctx.Diags.diagnose(loc, diag::sdk_version_pbm_version, SDKVer,
301+
diags.diagnose(loc, diag::sdk_version_pbm_version, SDKVer,
301302
PBMVer);
302303
}
303304
// We may have found multiple failing modules, that failed for different
304305
// reasons. Emit a note for each of them.
305306
for (auto &mod : outOfDateModules) {
306-
ctx.Diags.diagnose(loc, diag::out_of_date_module_here,
307+
diags.diagnose(loc, diag::out_of_date_module_here,
307308
(unsigned)mod.kind, mod.path);
308309

309310
// Diagnose any out-of-date dependencies in this module.
310311
for (auto &dep : mod.outOfDateDependencies) {
311-
ctx.Diags.diagnose(loc, diag::module_interface_dependency_out_of_date,
312+
diags.diagnose(loc, diag::module_interface_dependency_out_of_date,
312313
dep);
313314
}
314315

315316
// Diagnose any missing dependencies in this module.
316317
for (auto &dep : mod.missingDependencies) {
317-
ctx.Diags.diagnose(loc, diag::module_interface_dependency_missing, dep);
318+
diags.diagnose(loc, diag::module_interface_dependency_missing, dep);
318319
}
319320

320321
// If there was a compiled module that wasn't able to be read, diagnose
321322
// the reason we couldn't read it.
322323
if (auto status = mod.serializationStatus) {
323324
if (auto reason = invalidModuleReason(*status)) {
324-
ctx.Diags.diagnose(loc, diag::compiled_module_invalid_reason,
325+
diags.diagnose(loc, diag::compiled_module_invalid_reason,
325326
mod.path, reason);
326327
} else {
327-
ctx.Diags.diagnose(loc, diag::compiled_module_invalid, mod.path);
328+
diags.diagnose(loc, diag::compiled_module_invalid, mod.path);
328329
}
329330
}
330331
}
@@ -957,12 +958,33 @@ class ModuleInterfaceLoaderImpl {
957958
}
958959

959960
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
961+
960962
// We didn't discover a module corresponding to this interface.
961963
// Diagnose that we didn't find a loadable module, if we were asked to.
962-
auto remarkRebuild = [&]() {
963-
rebuildInfo.diagnose(ctx, diagnosticLoc, moduleName,
964-
interfacePath, prebuiltCacheDir);
964+
//
965+
// Note that we use `diags` so that we emit this remark even when we're
966+
// emitting other messages to `emptyDiags` (see below); these act as status
967+
// messages to explain what's taking so long.
968+
auto remarkRebuildAll = [&]() {
969+
rebuildInfo.diagnose(ctx, diags, prebuiltCacheDir, diagnosticLoc,
970+
diag::rebuilding_module_from_interface, moduleName,
971+
interfacePath);
972+
};
973+
// Diagnose only for the standard library; it should be prebuilt in typical
974+
// workflows, but if it isn't, building it may take several minutes and a
975+
// lot of memory, so users may think the compiler is busy-hung.
976+
auto remarkRebuildStdlib = [&]() {
977+
if (moduleName != "Swift")
978+
return;
979+
980+
auto moduleTriple = getTargetSpecificModuleTriple(ctx.LangOpts.Target);
981+
rebuildInfo.diagnose(ctx, diags, prebuiltCacheDir, SourceLoc(),
982+
diag::rebuilding_stdlib_from_interface,
983+
moduleTriple.str());
965984
};
985+
auto remarkRebuild = Opts.remarkOnRebuildFromInterface
986+
? llvm::function_ref<void()>(remarkRebuildAll)
987+
: remarkRebuildStdlib;
966988

967989
bool failed = false;
968990
std::string backupPath = getBackupPublicModuleInterfacePath();
@@ -996,11 +1018,8 @@ class ModuleInterfaceLoaderImpl {
9961018
if (rebuildInfo.sawOutOfDateModule(modulePath))
9971019
builder.addExtraDependency(modulePath);
9981020
failed = builder.buildSwiftModule(cachedOutputPath,
999-
/*shouldSerializeDeps*/true,
1000-
&moduleBuffer,
1001-
Opts.remarkOnRebuildFromInterface ?
1002-
remarkRebuild:
1003-
llvm::function_ref<void()>());
1021+
/*shouldSerializeDeps*/true,
1022+
&moduleBuffer, remarkRebuild);
10041023
}
10051024
if (!failed) {
10061025
// If succeeded, we are done.
@@ -1033,9 +1052,7 @@ class ModuleInterfaceLoaderImpl {
10331052
// calcualted using the canonical interface file path to make sure we
10341053
// can find it from the canonical interface file.
10351054
auto failedAgain = fallbackBuilder.buildSwiftModule(cachedOutputPath,
1036-
/*shouldSerializeDeps*/true, &moduleBuffer,
1037-
Opts.remarkOnRebuildFromInterface ? remarkRebuild:
1038-
llvm::function_ref<void()>());
1055+
/*shouldSerializeDeps*/true, &moduleBuffer, remarkRebuild);
10391056
if (failedAgain)
10401057
return std::make_error_code(std::errc::invalid_argument);
10411058
assert(moduleBuffer);

test/ModuleInterface/BadStdlib.swiftinterface

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// other things.)
1010

1111
// RUN: %empty-directory(%t)
12-
// RUN: %target-swift-frontend(mock-sdk: -sdk %/S/Inputs/BadStdlib.sdk -module-cache-path %/t/module-cache -resource-dir %/S/Inputs/BadStdlib.sdk) -compile-module-from-interface -o %/t/BadStdlib.swiftmodule %s -verify -verify-additional-file %/S/Inputs/BadStdlib.sdk/usr/lib/swift/Swift.swiftmodule/x86_64-apple-macos.swiftinterface
12+
// RUN: %target-swift-frontend(mock-sdk: -sdk %/S/Inputs/BadStdlib.sdk -module-cache-path %/t/module-cache -resource-dir %/S/Inputs/BadStdlib.sdk) -compile-module-from-interface -o %/t/BadStdlib.swiftmodule %s -verify -verify-additional-file %/S/Inputs/BadStdlib.sdk/usr/lib/swift/Swift.swiftmodule/x86_64-apple-macos.swiftinterface -verify-ignore-unknown
1313

1414
import ClangMod
1515

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -target x86_64-apple-macos10.9 -module-name OtherModule -O
3+
4+
import Swift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -target x86_64-apple-macos10.9 -module-name Swift -parse-stdlib
3+
4+
public struct Int {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -target x86_64-apple-macos10.9 -module-name _Concurrency -parse-stdlib
3+
4+
@frozen public enum Task {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %empty-directory(%t.mcps)
2+
3+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs/stdlib_rebuild -resource-dir %S/Inputs/stdlib_rebuild -module-cache-path %t.mcps/rebuild-remarks-off) -typecheck %s 2>&1 | %FileCheck -check-prefixes SLOW-DIAG,ALL %s
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs/stdlib_rebuild -resource-dir %S/Inputs/stdlib_rebuild -module-cache-path %t.mcps/rebuild-remarks-off) -typecheck %s 2>&1 | %FileCheck -check-prefixes ALL --allow-empty %s
5+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs/stdlib_rebuild -resource-dir %S/Inputs/stdlib_rebuild -module-cache-path %t.mcps/rebuild-remarks-off) -D OTHER_IMPORT -typecheck %s 2>&1 | %FileCheck -check-prefixes ALL --allow-empty %s
6+
7+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs/stdlib_rebuild -resource-dir %S/Inputs/stdlib_rebuild -module-cache-path %t.mcps/rebuild-remarks-on) -Rmodule-interface-rebuild -typecheck %s 2>&1 | %FileCheck -check-prefixes NORMAL-DIAG,ALL %s
8+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs/stdlib_rebuild -resource-dir %S/Inputs/stdlib_rebuild -module-cache-path %t.mcps/rebuild-remarks-on) -Rmodule-interface-rebuild -typecheck %s 2>&1 | %FileCheck -check-prefixes ALL --allow-empty %s
9+
10+
// Our test directory only contains interfaces for x86_64-apple-macos.
11+
// REQUIRES: CPU=x86_64
12+
// REQUIRES: OS=macosx
13+
14+
#if OTHER_IMPORT
15+
import OtherModule
16+
#endif
17+
18+
func fn(_: Int) {}
19+
20+
// SLOW-DIAG: remark: did not find a prebuilt standard library for target '{{.*}}' compatible with this Swift compiler; building it may take a few minutes, but it should only happen once for this combination of compiler and target
21+
22+
// NORMAL-DIAG-DAG: remark: rebuilding module 'Swift' from interface '{{.*}}'
23+
// NORMAL-DIAG-DAG: remark: rebuilding module '_Concurrency' from interface '{{.*}}'
24+
25+
// Used even when one of the above ones is also used, since the diagnostics should only be emitted once
26+
// ALL-NOT: remark: did not find a prebuilt standard library
27+
// ALL-NOT: remark: rebuilding module '{{Swift|_Concurrency}}' from interface '{{.*}}'

0 commit comments

Comments
 (0)