Skip to content

Commit 359385b

Browse files
tapthakerjrose-apple
authored andcommitted
Print proper error message when the swiftmodule for architecture not found (#17092)
https://bugs.swift.org/browse/SR-7160
1 parent 8f23048 commit 359385b

File tree

3 files changed

+94
-10
lines changed

3 files changed

+94
-10
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@ ERROR(cannot_return_value_from_void_func,none,
562562

563563
ERROR(sema_no_import,Fatal,
564564
"no such module '%0'", (StringRef))
565+
ERROR(sema_no_import_arch,Fatal,
566+
"could not find module '%0' for architecture '%1'; "
567+
"found: %2", (StringRef, StringRef, StringRef))
565568
ERROR(sema_no_import_repl,none,
566569
"no such module '%0'", (StringRef))
567570
NOTE(sema_no_import_no_sdk,none,

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,48 @@ openModuleFiles(StringRef DirName, StringRef ModuleFilename,
8181
return std::error_code();
8282
}
8383

84+
static void addDiagnosticInfoForArchitectureMismatch(ASTContext &ctx,
85+
SourceLoc sourceLocation,
86+
StringRef moduleName,
87+
StringRef archName,
88+
StringRef directoryPath) {
89+
90+
std::error_code errorCode;
91+
llvm::sys::fs::directory_iterator directoryIterator(directoryPath, errorCode,
92+
true);
93+
llvm::sys::fs::directory_iterator endIterator;
94+
95+
if (errorCode) {
96+
return;
97+
}
98+
99+
std::string foundArchs;
100+
for (; directoryIterator != endIterator;
101+
directoryIterator.increment(errorCode)) {
102+
if (errorCode) {
103+
return;
104+
}
105+
auto entry = *directoryIterator;
106+
StringRef filePath(entry.path());
107+
StringRef extension = llvm::sys::path::extension(filePath);
108+
if (extension.startswith(".") &&
109+
extension.drop_front() == SERIALIZED_MODULE_EXTENSION) {
110+
foundArchs = foundArchs + (foundArchs.length() > 0 ? ", " : "") +
111+
llvm::sys::path::stem(filePath).str();
112+
}
113+
}
114+
115+
ctx.Diags.diagnose(sourceLocation, diag::sema_no_import_arch, moduleName,
116+
archName, foundArchs);
117+
}
118+
84119
static bool
85120
findModule(ASTContext &ctx, AccessPathElem moduleID,
86121
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
87122
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
88123
bool &isFramework) {
89-
llvm::SmallString<64> moduleFilename(moduleID.first.str());
124+
llvm::SmallString<64> moduleName(moduleID.first.str());
125+
llvm::SmallString<64> moduleFilename(moduleName);
90126
moduleFilename += '.';
91127
moduleFilename += SERIALIZED_MODULE_EXTENSION;
92128

@@ -96,9 +132,10 @@ findModule(ASTContext &ctx, AccessPathElem moduleID,
96132

97133
// FIXME: Which name should we be using here? Do we care about CPU subtypes?
98134
// FIXME: At the very least, don't hardcode "arch".
99-
llvm::SmallString<16> archFile{
135+
llvm::SmallString<16> archName{
100136
ctx.LangOpts.getPlatformConditionValue(PlatformConditionKind::Arch)};
101-
llvm::SmallString<16> archDocFile{archFile};
137+
llvm::SmallString<16> archFile{archName};
138+
llvm::SmallString<16> archDocFile{archName};
102139
if (!archFile.empty()) {
103140
archFile += '.';
104141
archFile += SERIALIZED_MODULE_EXTENSION;
@@ -122,6 +159,12 @@ findModule(ASTContext &ctx, AccessPathElem moduleID,
122159
archFile.str(), archDocFile.str(),
123160
moduleBuffer, moduleDocBuffer,
124161
scratch);
162+
163+
if (err == std::errc::no_such_file_or_directory) {
164+
addDiagnosticInfoForArchitectureMismatch(
165+
ctx, moduleID.second, moduleName, archName, currPath);
166+
return false;
167+
}
125168
}
126169
if (!err)
127170
return true;
@@ -134,12 +177,22 @@ findModule(ASTContext &ctx, AccessPathElem moduleID,
134177

135178
auto tryFrameworkImport = [&](StringRef frameworkPath) -> bool {
136179
currPath = frameworkPath;
137-
llvm::sys::path::append(currPath, moduleFramework.str(),
138-
"Modules", moduleFilename.str());
139-
auto err = openModuleFiles(currPath,
140-
archFile.str(), archDocFile.str(),
141-
moduleBuffer, moduleDocBuffer,
142-
scratch);
180+
llvm::sys::path::append(currPath, moduleFramework.str());
181+
// Check if the framework directory exists
182+
if (!llvm::sys::fs::is_directory(currPath)) {
183+
return false;
184+
}
185+
186+
llvm::sys::path::append(currPath, "Modules", moduleFilename.str());
187+
auto err = openModuleFiles(currPath, archFile.str(), archDocFile.str(),
188+
moduleBuffer, moduleDocBuffer, scratch);
189+
190+
if (err == std::errc::no_such_file_or_directory) {
191+
addDiagnosticInfoForArchitectureMismatch(
192+
ctx, moduleID.second, moduleName, archName, currPath);
193+
return false;
194+
}
195+
143196
return !err;
144197
};
145198

@@ -649,4 +702,4 @@ SerializedASTFile::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
649702
Identifier discriminator = File.getDiscriminatorForPrivateValue(D);
650703
assert(!discriminator.empty() && "no discriminator found for value");
651704
return discriminator;
652-
}
705+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
// RUN: %empty-directory(%t)
3+
// RUN: mkdir %t/new_module.swiftmodule
4+
// RUN: touch %t/new_module.swiftmodule/i387.swiftmodule
5+
// RUN: touch %t/new_module.swiftmodule/ppc65.swiftmodule
6+
// RUN: touch %t/new_module.swiftmodule/i387.swiftdoc
7+
// RUN: touch %t/new_module.swiftmodule/ppc65.swiftdoc
8+
// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -DTARGET_ARCHITECTURE=%target-cpu
9+
10+
// RUN: %empty-directory(%t)
11+
// RUN: mkdir -p %t/new_module.framework/Modules/new_module.swiftmodule/
12+
// RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/i387.swiftmodule
13+
// RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/ppc65.swiftmodule
14+
// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -DTARGET_ARCHITECTURE=%target-cpu
15+
16+
//CHECK: {{.*}} error: could not find module 'new_module' for architecture '[[TARGET_ARCHITECTURE]]'; found: {{ppc65, i387|i387, ppc65}}
17+
//CHECK-NEXT: import new_module
18+
//CHECK-NEXT: ^
19+
//CHECK: error: no such module 'new_module'
20+
//CHECK-NEXT: import new_module
21+
//CHECK-NEXT: ^
22+
//CHECK: error: use of unresolved identifier 'new_module'
23+
//CHECK-NEXT: new_module.foo()
24+
//CHECK-NEXT: ^~~~~~~~~~
25+
26+
import new_module
27+
28+
new_module.foo()

0 commit comments

Comments
 (0)