Skip to content

Commit d67d7eb

Browse files
author
Harlan Haskins
authored
[Serialization] Look for cross-ref errors inside type errors (swiftlang#33271)
In swiftlang#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.
1 parent 7e60a73 commit d67d7eb

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5951,6 +5951,33 @@ void ModuleFile::loadAllMembers(Decl *container, uint64_t contextData) {
59515951
}
59525952
}
59535953

5954+
static llvm::Error consumeErrorIfXRefNonLoadedModule(llvm::Error &&error) {
5955+
// Missing module errors are most likely caused by an
5956+
// implementation-only import hiding types and decls.
5957+
// rdar://problem/60291019
5958+
if (error.isA<XRefNonLoadedModuleError>()) {
5959+
consumeError(std::move(error));
5960+
return llvm::Error::success();
5961+
}
5962+
5963+
// Some of these errors may manifest as a TypeError with an
5964+
// XRefNonLoadedModuleError underneath. Catch those as well.
5965+
// rdar://66491720
5966+
if (error.isA<TypeError>()) {
5967+
auto errorInfo = takeErrorInfo(std::move(error));
5968+
auto *TE = static_cast<TypeError*>(errorInfo.get());
5969+
5970+
if (TE->underlyingReasonIsA<XRefNonLoadedModuleError>()) {
5971+
consumeError(std::move(errorInfo));
5972+
return llvm::Error::success();
5973+
}
5974+
5975+
return std::move(errorInfo);
5976+
}
5977+
5978+
return std::move(error);
5979+
}
5980+
59545981
void
59555982
ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
59565983
SmallVectorImpl<ProtocolConformance*> &conformances) {
@@ -5968,15 +5995,11 @@ ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
59685995
auto conformance = readConformanceChecked(DeclTypeCursor);
59695996

59705997
if (!conformance) {
5971-
// Missing module errors are most likely caused by an
5972-
// implementation-only import hiding types and decls.
5973-
// rdar://problem/60291019
5974-
if (conformance.errorIsA<XRefNonLoadedModuleError>()) {
5975-
consumeError(conformance.takeError());
5976-
return;
5977-
}
5978-
else
5979-
fatal(conformance.takeError());
5998+
auto unconsumedError =
5999+
consumeErrorIfXRefNonLoadedModule(conformance.takeError());
6000+
if (unconsumedError)
6001+
fatal(std::move(unconsumedError));
6002+
return;
59806003
}
59816004

59826005
if (conformance.get().isConcrete())

lib/Serialization/DeserializationErrors.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,13 @@ class TypeError : public llvm::ErrorInfo<TypeError, DeclDeserializationError> {
352352
this->numVTableEntries = numVTableEntries;
353353
}
354354

355+
template <typename UnderlyingErrorT>
356+
bool underlyingReasonIsA() const {
357+
if (!underlyingReason)
358+
return false;
359+
return underlyingReason->isA<UnderlyingErrorT>();
360+
}
361+
355362
void log(raw_ostream &OS) const override {
356363
OS << "could not deserialize type for '" << name << "'";
357364
if (underlyingReason) {

test/Serialization/Recovery/implementation-only-missing.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,24 @@ struct StructWithOverride: HiddenProtocolWithOverride {
8181
func hiddenOverride() {}
8282
}
8383

84+
internal protocol RefinesHiddenProtocol: HiddenProtocol {
85+
86+
}
87+
88+
public struct PublicStructConformsToHiddenProtocol: RefinesHiddenProtocol {
89+
public typealias Value = Int
90+
91+
public init() { }
92+
}
93+
8494
#elseif CLIENT_APP
8595

8696
import public_lib
8797

8898
var s = PublicStruct()
8999
print(s.nonWrappedVar)
90100

101+
var p = PublicStructConformsToHiddenProtocol()
102+
print(p)
103+
91104
#endif

0 commit comments

Comments
 (0)