Skip to content

Commit df01027

Browse files
committed
[Dependency Scanning] Diagnose an error when only finding incompatible Swift binary modules
When querying a Swift module, the scanner now also keeps track of all discovered candidate binary modules which are not compatible with current compilation. - If a Swift dependency is successfully resolved to a compatible binary module or a textual interface, a warning is emitted for every incompatible binary Swift module discovered along the way. - If a Swift dependency is not resolved, but incompatible module candidates were found, an error is emitted - while it is likely that the scan would fail downstream, it is also possible that an underlying Clang module dependency (with the same name) is successfuly resolved and the Swift lookup failure is ignored, which is still going to lead to failures most of the time if the client code assumes the presence of the Swift overlay module in this scenario. This change refactors common error reporting by the scanner into a 'ModuleDependencyIssueReporter' class, which also keeps track of all diagnosed failed lookups to avoid repeating diagnostics.
1 parent 39c096c commit df01027

15 files changed

+291
-143
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,15 +1290,6 @@ REMARK(module_api_import_aliases,none,
12901290
"%select{, which reexports definition from %2|}3",
12911291
(const Decl *, ModuleDecl *, ModuleDecl *, bool))
12921292

1293-
REMARK(dependency_scan_skip_module_invalid,none,
1294-
"module file '%0' skipped by the dependency scan because it is "
1295-
"incompatible with this Swift compiler: %1", (StringRef, StringRef))
1296-
WARNING(skip_module_not_testable,none,
1297-
"ignore swiftmodule built without '-enable-testing': %0", (StringRef))
1298-
WARNING(dependency_scan_module_incompatible, none,
1299-
"module file '%0' is incompatible with this Swift compiler: %1",
1300-
(StringRef, StringRef))
1301-
13021293
REMARK(macro_loaded,none,
13031294
"loaded macro implementation module %0 from "
13041295
"%select{shared library '%2'|executable '%2'|"
@@ -2377,9 +2368,11 @@ ERROR(alignment_not_power_of_two,none,
23772368
"alignment value must be a power of two", ())
23782369

23792370
// Dependency Scanning
2380-
ERROR(dependency_scan_module_not_found, none, "Unable to find module dependency: '%0'", (StringRef))
2371+
ERROR(dependency_scan_module_not_found, none, "unable to resolve module dependency: '%0'", (StringRef))
2372+
23812373
GROUPED_ERROR(dependency_scan_module_not_found_on_specified_search_paths, MissingModuleOnKnownPaths, none,
2382-
"Compilation search paths unable to resolve module dependency: '%0'", (StringRef))
2374+
"compilation search paths unable to resolve module dependency: '%0'", (StringRef))
2375+
23832376
NOTE(unresolved_import_location,none,
23842377
"also imported here", ())
23852378
NOTE(dependency_as_imported_by_main_module,none,
@@ -2388,10 +2381,21 @@ NOTE(dependency_as_imported_by, none,
23882381
"a dependency of %select{Swift|Clang}2 module '%0': '%1'", (StringRef, StringRef, bool))
23892382
NOTE(inherited_search_path_resolves_module,none,
23902383
"'%0' can be found using a search path that was specified when building module '%1' ('%2'). "
2391-
"This search path was not explicitly specified on the current compilation.", (StringRef, StringRef, StringRef))
2384+
"This search path was not explicitly specified on the current compilation", (StringRef, StringRef, StringRef))
2385+
2386+
ERROR(dependency_scan_compatible_swift_module_not_found, none,
2387+
"unable to resolve Swift module dependency to a compatible module: '%0'",
2388+
(StringRef))
2389+
NOTE(dependency_scan_incompatible_module_found,none,
2390+
"found incompatible module '%0': %1", (StringRef, StringRef))
2391+
2392+
WARNING(dependency_scan_module_incompatible, none,
2393+
"module file '%0' is incompatible with this Swift compiler: %1",
2394+
(StringRef, StringRef))
2395+
2396+
ERROR(clang_dependency_scan_error, none, "clang dependency scanning failure: %0", (StringRef))
23922397

2393-
ERROR(clang_dependency_scan_error, none, "Clang dependency scanner failure: %0", (StringRef))
2394-
ERROR(clang_header_dependency_scan_error, none, "Bridging header dependency scan failure: %0", (StringRef))
2398+
ERROR(clang_header_dependency_scan_error, none, "bridging header dependency scanning failure: %0", (StringRef))
23952399

23962400
// Enum annotations
23972401
ERROR(indirect_case_without_payload,none,

include/swift/AST/ModuleDependencies.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ struct ScannerImportStatementInfo {
133133
uint32_t columnNumber;
134134
};
135135

136+
ScannerImportStatementInfo(std::string importIdentifier)
137+
: importIdentifier(importIdentifier), importLocations(),
138+
isExported(false), accessLevel(AccessLevel::Public) {}
139+
136140
ScannerImportStatementInfo(std::string importIdentifier, bool isExported,
137141
AccessLevel accessLevel)
138142
: importIdentifier(importIdentifier), importLocations(),

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ModuleDependencyScanningWorker {
4343
&alreadySeenModules);
4444

4545
/// Retrieve the module dependencies for the Swift module with the given name.
46-
ModuleDependencyVector scanFilesystemForSwiftModuleDependency(
46+
SwiftModuleScannerQueryResult scanFilesystemForSwiftModuleDependency(
4747
Identifier moduleName, bool isTestableImport = false);
4848

4949
/// Query dependency information for header dependencies
@@ -112,6 +112,46 @@ class ModuleDependencyScanningWorker {
112112
friend class ModuleDependencyScanner;
113113
};
114114

115+
class ModuleDependencyIssueReporter {
116+
private:
117+
ModuleDependencyIssueReporter(DiagnosticEngine &Diagnostics)
118+
: Diagnostics(Diagnostics) {}
119+
120+
/// Diagnose scanner failure and attempt to reconstruct the dependency
121+
/// path from the main module to the missing dependency
122+
void diagnoseModuleNotFoundFailure(
123+
const ScannerImportStatementInfo &moduleImport,
124+
const ModuleDependenciesCache &cache,
125+
std::optional<ModuleDependencyID> dependencyOf,
126+
std::optional<std::pair<ModuleDependencyID, std::string>>
127+
resolvingSerializedSearchPath,
128+
std::optional<
129+
std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>>
130+
foundIncompatibleCandidates = std::nullopt);
131+
132+
/// Upon query failure, if incompatible binary module
133+
/// candidates were found, emit a failure diagnostic
134+
void diagnoseFailureOnOnlyIncompatibleCandidates(
135+
const ScannerImportStatementInfo &moduleImport,
136+
const std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>
137+
&candidates,
138+
const ModuleDependenciesCache &cache,
139+
std::optional<ModuleDependencyID> dependencyOf);
140+
141+
/// Emit warnings for each discovered binary Swift module
142+
/// which was incompatible with the current compilation
143+
/// when querying \c moduleName
144+
void warnOnIncompatibleCandidates(
145+
StringRef moduleName,
146+
const std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>
147+
&candidates);
148+
149+
DiagnosticEngine &Diagnostics;
150+
std::unordered_set<std::string> ReportedMissing;
151+
// Restrict access to the parent scanner class.
152+
friend class ModuleDependencyScanner;
153+
};
154+
115155
class ModuleDependencyScanner {
116156
public:
117157
ModuleDependencyScanner(SwiftDependencyScanningService &ScanningService,
@@ -182,7 +222,7 @@ class ModuleDependencyScanner {
182222
StringRef mainModuleName, ModuleDependenciesCache &cache,
183223
llvm::function_ref<void(ModuleDependencyID)> action);
184224

185-
/// Performance BridgingHeader Chaining.
225+
/// Perform Bridging Header Chaining.
186226
llvm::Error
187227
performBridgingHeaderChaining(const ModuleDependencyID &rootModuleID,
188228
ModuleDependenciesCache &cache,
@@ -197,12 +237,6 @@ class ModuleDependencyScanner {
197237
/// for a given module name.
198238
Identifier getModuleImportIdentifier(StringRef moduleName);
199239

200-
/// Diagnose scanner failure and attempt to reconstruct the dependency
201-
/// path from the main module to the missing dependency.
202-
void diagnoseScannerFailure(const ScannerImportStatementInfo &moduleImport,
203-
const ModuleDependenciesCache &cache,
204-
std::optional<ModuleDependencyID> dependencyOf);
205-
206240
/// Assuming the \c `moduleImport` failed to resolve,
207241
/// iterate over all binary Swift module dependencies with serialized
208242
/// search paths and attempt to diagnose if the failed-to-resolve module
@@ -211,12 +245,12 @@ class ModuleDependencyScanner {
211245
std::optional<std::pair<ModuleDependencyID, std::string>>
212246
attemptToFindResolvingSerializedSearchPath(
213247
const ScannerImportStatementInfo &moduleImport,
214-
const ModuleDependenciesCache &cache, const SourceLoc &importLoc);
248+
const ModuleDependenciesCache &cache);
215249

216250
private:
217251
const CompilerInvocation &ScanCompilerInvocation;
218252
ASTContext &ScanASTContext;
219-
DiagnosticEngine &Diagnostics;
253+
ModuleDependencyIssueReporter IssueReporter;
220254

221255
/// The available pool of workers for filesystem module search
222256
unsigned NumThreads;

include/swift/Serialization/ScanningLoaders.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
#include "swift/Serialization/SerializedModuleLoader.h"
1919

2020
namespace swift {
21+
22+
/// Result of looking up a Swift module on the current filesystem
23+
/// search paths.
24+
struct SwiftModuleScannerQueryResult {
25+
struct IncompatibleCandidate {
26+
std::string path;
27+
std::string incompatibilityReason;
28+
};
29+
30+
std::vector<IncompatibleCandidate> incompatibleCandidates;
31+
std::optional<ModuleDependencyInfo> foundDependencyInfo;
32+
};
33+
2134
/// A module "loader" that looks for .swiftinterface and .swiftmodule files
2235
/// for the purpose of determining dependencies, but does not attempt to
2336
/// load the module files.
@@ -60,7 +73,8 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase {
6073
std::vector<std::string> swiftModuleClangCC1CommandLineArgs;
6174

6275
public:
63-
std::optional<ModuleDependencyInfo> dependencies;
76+
std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate> incompatibleCandidates;
77+
std::optional<ModuleDependencyInfo> foundDependencyInfo;
6478

6579
SwiftModuleScanner(ASTContext &ctx, ModuleLoadingMode LoadMode,
6680
InterfaceSubContextDelegate &astDelegate,
@@ -74,7 +88,7 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase {
7488
swiftModuleClangCC1CommandLineArgs(swiftModuleClangCC1CommandLineArgs) {}
7589

7690
/// Perform a filesystem search for a Swift module with a given name
77-
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
91+
SwiftModuleScannerQueryResult
7892
lookupSwiftModule(Identifier moduleName, bool isTestableImport);
7993
};
8094
} // namespace swift

0 commit comments

Comments
 (0)