Merge pull request #30614 from xymus/fix-deser-indexing

[Serialization] Recover from more failures when reading private declarations
This commit is contained in:
Alexis Laferrière
2020-03-24 13:45:00 -07:00
committed by GitHub
3 changed files with 75 additions and 21 deletions

View File

@@ -527,7 +527,10 @@ ModuleFile::readConformanceChecked(llvm::BitstreamCursor &Cursor,
"reading specialized conformance for", "reading specialized conformance for",
conformingType); conformingType);
auto subMap = getSubstitutionMap(substitutionMapID); auto subMapOrError = getSubstitutionMapChecked(substitutionMapID);
if (!subMapOrError)
return subMapOrError.takeError();
auto subMap = subMapOrError.get();
ProtocolConformanceRef genericConformance = ProtocolConformanceRef genericConformance =
readConformance(Cursor, genericEnv); readConformance(Cursor, genericEnv);
@@ -571,7 +574,11 @@ ModuleFile::readConformanceChecked(llvm::BitstreamCursor &Cursor,
case NORMAL_PROTOCOL_CONFORMANCE_ID: { case NORMAL_PROTOCOL_CONFORMANCE_ID: {
NormalConformanceID conformanceID; NormalConformanceID conformanceID;
NormalProtocolConformanceIdLayout::readRecord(scratch, conformanceID); NormalProtocolConformanceIdLayout::readRecord(scratch, conformanceID);
return ProtocolConformanceRef(readNormalConformance(conformanceID));
auto conformance = readNormalConformanceChecked(conformanceID);
if (!conformance)
return conformance.takeError();
return ProtocolConformanceRef(conformance.get());
} }
case PROTOCOL_CONFORMANCE_XREF: { case PROTOCOL_CONFORMANCE_XREF: {
@@ -614,7 +621,7 @@ ModuleFile::readConformanceChecked(llvm::BitstreamCursor &Cursor,
} }
} }
NormalProtocolConformance *ModuleFile::readNormalConformance( Expected<NormalProtocolConformance *> ModuleFile::readNormalConformanceChecked(
NormalConformanceID conformanceID) { NormalConformanceID conformanceID) {
auto &conformanceEntry = NormalConformances[conformanceID-1]; auto &conformanceEntry = NormalConformances[conformanceID-1];
if (conformanceEntry.isComplete()) { if (conformanceEntry.isComplete()) {
@@ -647,13 +654,21 @@ NormalProtocolConformance *ModuleFile::readNormalConformance(
rawIDs); rawIDs);
ASTContext &ctx = getContext(); ASTContext &ctx = getContext();
DeclContext *dc = getDeclContext(contextID); auto doOrError = getDeclContextChecked(contextID);
if (!doOrError)
return doOrError.takeError();
DeclContext *dc = doOrError.get();
assert(!isa<ClangModuleUnit>(dc->getModuleScopeContext()) assert(!isa<ClangModuleUnit>(dc->getModuleScopeContext())
&& "should not have serialized a conformance from a clang module"); && "should not have serialized a conformance from a clang module");
Type conformingType = dc->getDeclaredInterfaceType(); Type conformingType = dc->getDeclaredInterfaceType();
PrettyStackTraceType trace(ctx, "reading conformance for", conformingType); PrettyStackTraceType trace(ctx, "reading conformance for", conformingType);
auto proto = cast<ProtocolDecl>(getDecl(protoID)); auto protoOrError = getDeclChecked(protoID);
if (!protoOrError)
return protoOrError.takeError();
auto proto = cast<ProtocolDecl>(protoOrError.get());
PrettyStackTraceDecl traceTo("... to", proto); PrettyStackTraceDecl traceTo("... to", proto);
++NumNormalProtocolConformancesLoaded; ++NumNormalProtocolConformancesLoaded;
@@ -1069,7 +1084,10 @@ ModuleFile::getSubstitutionMapChecked(serialization::SubstitutionMapID id) {
conformances.reserve(numConformances); conformances.reserve(numConformances);
for (unsigned i : range(numConformances)) { for (unsigned i : range(numConformances)) {
(void)i; (void)i;
conformances.push_back(readConformance(DeclTypeCursor)); auto conformanceOrError = readConformanceChecked(DeclTypeCursor);
if (!conformanceOrError)
return conformanceOrError.takeError();
conformances.push_back(conformanceOrError.get());
} }
// Form the substitution map and record it. // Form the substitution map and record it.
@@ -2798,7 +2816,10 @@ public:
var->setIsSetterMutating(isSetterMutating); var->setIsSetterMutating(isSetterMutating);
declOrOffset = var; declOrOffset = var;
Type interfaceType = MF.getType(interfaceTypeID); auto interfaceTypeOrError = MF.getTypeChecked(interfaceTypeID);
if (!interfaceTypeOrError)
return interfaceTypeOrError.takeError();
Type interfaceType = interfaceTypeOrError.get();
var->setInterfaceType(interfaceType); var->setInterfaceType(interfaceType);
var->setImplicitlyUnwrappedOptional(isIUO); var->setImplicitlyUnwrappedOptional(isIUO);
@@ -3221,9 +3242,12 @@ public:
auto genericSig = MF.getGenericSignature(genericSigID); auto genericSig = MF.getGenericSignature(genericSigID);
if (genericSig) if (genericSig)
opaqueDecl->setGenericSignature(genericSig); opaqueDecl->setGenericSignature(genericSig);
if (underlyingTypeID) if (underlyingTypeID) {
opaqueDecl->setUnderlyingTypeSubstitutions( auto subMapOrError = MF.getSubstitutionMapChecked(underlyingTypeID);
MF.getSubstitutionMap(underlyingTypeID)); if (!subMapOrError)
return subMapOrError.takeError();
opaqueDecl->setUnderlyingTypeSubstitutions(subMapOrError.get());
}
SubstitutionMap subs; SubstitutionMap subs;
if (genericSig) { if (genericSig) {
subs = genericSig->getIdentitySubstitutionMap(); subs = genericSig->getIdentitySubstitutionMap();
@@ -5102,7 +5126,11 @@ public:
decls_block::OpaqueArchetypeTypeLayout::readRecord(scratch, decls_block::OpaqueArchetypeTypeLayout::readRecord(scratch,
opaqueDeclID, subsID); opaqueDeclID, subsID);
auto opaqueDecl = cast<OpaqueTypeDecl>(MF.getDecl(opaqueDeclID)); auto opaqueTypeOrError = MF.getDeclChecked(opaqueDeclID);
if (!opaqueTypeOrError)
return opaqueTypeOrError.takeError();
auto opaqueDecl = cast<OpaqueTypeDecl>(opaqueTypeOrError.get());
auto subs = MF.getSubstitutionMap(subsID); auto subs = MF.getSubstitutionMap(subsID);
return OpaqueTypeArchetypeType::get(opaqueDecl, subs); return OpaqueTypeArchetypeType::get(opaqueDecl, subs);
@@ -5827,9 +5855,22 @@ ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
fatalIfNotSuccess(DeclTypeCursor.JumpToBit(bitPosition)); fatalIfNotSuccess(DeclTypeCursor.JumpToBit(bitPosition));
while (numConformances--) { while (numConformances--) {
auto conf = readConformance(DeclTypeCursor); auto conformance = readConformanceChecked(DeclTypeCursor);
if (conf.isConcrete())
conformances.push_back(conf.getConcrete()); 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());
}
if (conformance.get().isConcrete())
conformances.push_back(conformance.get().getConcrete());
} }
} }

View File

@@ -978,13 +978,14 @@ public:
llvm::Expected<ProtocolConformanceRef> llvm::Expected<ProtocolConformanceRef>
readConformanceChecked(llvm::BitstreamCursor &Cursor, readConformanceChecked(llvm::BitstreamCursor &Cursor,
GenericEnvironment *genericEnv = nullptr); GenericEnvironment *genericEnv = nullptr);
/// Read a SILLayout from the given cursor. /// Read a SILLayout from the given cursor.
SILLayout *readSILLayout(llvm::BitstreamCursor &Cursor); SILLayout *readSILLayout(llvm::BitstreamCursor &Cursor);
/// Read the given normal conformance from the current module file. /// Read the given normal conformance from the current module file,
NormalProtocolConformance * /// returns the conformance or the first error.
readNormalConformance(serialization::NormalConformanceID id); llvm::Expected<NormalProtocolConformance *>
readNormalConformanceChecked(serialization::NormalConformanceID id);
/// Reads a foreign error conformance from \c DeclTypeCursor, if present. /// Reads a foreign error conformance from \c DeclTypeCursor, if present.
Optional<ForeignErrorConvention> maybeReadForeignErrorConvention(); Optional<ForeignErrorConvention> maybeReadForeignErrorConvention();

View File

@@ -15,6 +15,10 @@
// RUN: %target-swift-frontend -typecheck -DCLIENT_APP -primary-file %s -I %t -index-system-modules -index-store-path %t // RUN: %target-swift-frontend -typecheck -DCLIENT_APP -primary-file %s -I %t -index-system-modules -index-store-path %t
// RUN: %target-swift-frontend -emit-sil -DCLIENT_APP -primary-file %s -I %t -module-name client // RUN: %target-swift-frontend -emit-sil -DCLIENT_APP -primary-file %s -I %t -module-name client
//// Printing the public module should not crash when checking for overrides of
//// methods from the private module.
// RUN: %target-swift-ide-test -print-module -module-to-print=public_lib -source-filename=x -skip-overrides -I %t
#if PRIVATE_LIB #if PRIVATE_LIB
@propertyWrapper @propertyWrapper
@@ -38,11 +42,15 @@ public protocol HiddenProtocol {
associatedtype Value associatedtype Value
} }
public protocol HiddenProtocolWithOverride {
func hiddenOverride()
}
#elseif PUBLIC_LIB #elseif PUBLIC_LIB
@_implementationOnly import private_lib @_implementationOnly import private_lib
struct LibProtocolContraint { } struct LibProtocolConstraint { }
protocol LibProtocolTABound { } protocol LibProtocolTABound { }
struct LibProtocolTA: LibProtocolTABound { } struct LibProtocolTA: LibProtocolTABound { }
@@ -52,13 +60,13 @@ protocol LibProtocol {
func hiddenRequirement<A>( func hiddenRequirement<A>(
param: HiddenGenStruct<A> param: HiddenGenStruct<A>
) where A.Value == LibProtocolContraint ) where A.Value == LibProtocolConstraint
} }
extension LibProtocol where TA == LibProtocolTA { extension LibProtocol where TA == LibProtocolTA {
func hiddenRequirement<A>( func hiddenRequirement<A>(
param: HiddenGenStruct<A> param: HiddenGenStruct<A>
) where A.Value == LibProtocolContraint { } ) where A.Value == LibProtocolConstraint { }
} }
public struct PublicStruct: LibProtocol { public struct PublicStruct: LibProtocol {
@@ -70,6 +78,10 @@ public struct PublicStruct: LibProtocol {
public var wrappedVar: String public var wrappedVar: String
} }
struct StructWithOverride: HiddenProtocolWithOverride {
func hiddenOverride() {}
}
#elseif CLIENT_APP #elseif CLIENT_APP
import public_lib import public_lib