[Serialization] Look for cross-ref errors inside type errors (#33271)

In #30614, we started consuming XRefNonLoadedModuleErrors while loading
conformances, since a conformance to a type we cannot load usually
indicates we're trying to load a protocol that was declared in an
@_implementationOnly imported module.

We should also consume TypeErrors that we see where the underlying reason
is an XRefNonLoadedModuleError, since they're likely indicators of the
same thing.
This commit is contained in:
Harlan Haskins
2020-08-04 13:04:14 -07:00
committed by GitHub
parent 7e60a73335
commit d67d7ebc0a
3 changed files with 52 additions and 9 deletions

View File

@@ -5951,6 +5951,33 @@ void ModuleFile::loadAllMembers(Decl *container, uint64_t contextData) {
}
}
static llvm::Error consumeErrorIfXRefNonLoadedModule(llvm::Error &&error) {
// Missing module errors are most likely caused by an
// implementation-only import hiding types and decls.
// rdar://problem/60291019
if (error.isA<XRefNonLoadedModuleError>()) {
consumeError(std::move(error));
return llvm::Error::success();
}
// Some of these errors may manifest as a TypeError with an
// XRefNonLoadedModuleError underneath. Catch those as well.
// rdar://66491720
if (error.isA<TypeError>()) {
auto errorInfo = takeErrorInfo(std::move(error));
auto *TE = static_cast<TypeError*>(errorInfo.get());
if (TE->underlyingReasonIsA<XRefNonLoadedModuleError>()) {
consumeError(std::move(errorInfo));
return llvm::Error::success();
}
return std::move(errorInfo);
}
return std::move(error);
}
void
ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
SmallVectorImpl<ProtocolConformance*> &conformances) {
@@ -5968,15 +5995,11 @@ ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
auto conformance = readConformanceChecked(DeclTypeCursor);
if (!conformance) {
// Missing module errors are most likely caused by an
// implementation-only import hiding types and decls.
// rdar://problem/60291019
if (conformance.errorIsA<XRefNonLoadedModuleError>()) {
consumeError(conformance.takeError());
return;
}
else
fatal(conformance.takeError());
auto unconsumedError =
consumeErrorIfXRefNonLoadedModule(conformance.takeError());
if (unconsumedError)
fatal(std::move(unconsumedError));
return;
}
if (conformance.get().isConcrete())