Skip to content

Commit 9921cd7

Browse files
authored
Merge pull request swiftlang#30614 from xymus/fix-deser-indexing
[Serialization] Recover from more failures when reading private declarations
2 parents f0cdd76 + c133437 commit 9921cd7

File tree

3 files changed

+75
-21
lines changed

3 files changed

+75
-21
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,10 @@ ModuleFile::readConformanceChecked(llvm::BitstreamCursor &Cursor,
527527
"reading specialized conformance for",
528528
conformingType);
529529

530-
auto subMap = getSubstitutionMap(substitutionMapID);
530+
auto subMapOrError = getSubstitutionMapChecked(substitutionMapID);
531+
if (!subMapOrError)
532+
return subMapOrError.takeError();
533+
auto subMap = subMapOrError.get();
531534

532535
ProtocolConformanceRef genericConformance =
533536
readConformance(Cursor, genericEnv);
@@ -571,7 +574,11 @@ ModuleFile::readConformanceChecked(llvm::BitstreamCursor &Cursor,
571574
case NORMAL_PROTOCOL_CONFORMANCE_ID: {
572575
NormalConformanceID conformanceID;
573576
NormalProtocolConformanceIdLayout::readRecord(scratch, conformanceID);
574-
return ProtocolConformanceRef(readNormalConformance(conformanceID));
577+
578+
auto conformance = readNormalConformanceChecked(conformanceID);
579+
if (!conformance)
580+
return conformance.takeError();
581+
return ProtocolConformanceRef(conformance.get());
575582
}
576583

577584
case PROTOCOL_CONFORMANCE_XREF: {
@@ -614,7 +621,7 @@ ModuleFile::readConformanceChecked(llvm::BitstreamCursor &Cursor,
614621
}
615622
}
616623

617-
NormalProtocolConformance *ModuleFile::readNormalConformance(
624+
Expected<NormalProtocolConformance *> ModuleFile::readNormalConformanceChecked(
618625
NormalConformanceID conformanceID) {
619626
auto &conformanceEntry = NormalConformances[conformanceID-1];
620627
if (conformanceEntry.isComplete()) {
@@ -647,13 +654,21 @@ NormalProtocolConformance *ModuleFile::readNormalConformance(
647654
rawIDs);
648655

649656
ASTContext &ctx = getContext();
650-
DeclContext *dc = getDeclContext(contextID);
657+
auto doOrError = getDeclContextChecked(contextID);
658+
if (!doOrError)
659+
return doOrError.takeError();
660+
DeclContext *dc = doOrError.get();
661+
651662
assert(!isa<ClangModuleUnit>(dc->getModuleScopeContext())
652663
&& "should not have serialized a conformance from a clang module");
653664
Type conformingType = dc->getDeclaredInterfaceType();
654665
PrettyStackTraceType trace(ctx, "reading conformance for", conformingType);
655666

656-
auto proto = cast<ProtocolDecl>(getDecl(protoID));
667+
auto protoOrError = getDeclChecked(protoID);
668+
if (!protoOrError)
669+
return protoOrError.takeError();
670+
auto proto = cast<ProtocolDecl>(protoOrError.get());
671+
657672
PrettyStackTraceDecl traceTo("... to", proto);
658673
++NumNormalProtocolConformancesLoaded;
659674

@@ -1069,7 +1084,10 @@ ModuleFile::getSubstitutionMapChecked(serialization::SubstitutionMapID id) {
10691084
conformances.reserve(numConformances);
10701085
for (unsigned i : range(numConformances)) {
10711086
(void)i;
1072-
conformances.push_back(readConformance(DeclTypeCursor));
1087+
auto conformanceOrError = readConformanceChecked(DeclTypeCursor);
1088+
if (!conformanceOrError)
1089+
return conformanceOrError.takeError();
1090+
conformances.push_back(conformanceOrError.get());
10731091
}
10741092

10751093
// Form the substitution map and record it.
@@ -2798,7 +2816,10 @@ class DeclDeserializer {
27982816
var->setIsSetterMutating(isSetterMutating);
27992817
declOrOffset = var;
28002818

2801-
Type interfaceType = MF.getType(interfaceTypeID);
2819+
auto interfaceTypeOrError = MF.getTypeChecked(interfaceTypeID);
2820+
if (!interfaceTypeOrError)
2821+
return interfaceTypeOrError.takeError();
2822+
Type interfaceType = interfaceTypeOrError.get();
28022823
var->setInterfaceType(interfaceType);
28032824
var->setImplicitlyUnwrappedOptional(isIUO);
28042825

@@ -3221,9 +3242,12 @@ class DeclDeserializer {
32213242
auto genericSig = MF.getGenericSignature(genericSigID);
32223243
if (genericSig)
32233244
opaqueDecl->setGenericSignature(genericSig);
3224-
if (underlyingTypeID)
3225-
opaqueDecl->setUnderlyingTypeSubstitutions(
3226-
MF.getSubstitutionMap(underlyingTypeID));
3245+
if (underlyingTypeID) {
3246+
auto subMapOrError = MF.getSubstitutionMapChecked(underlyingTypeID);
3247+
if (!subMapOrError)
3248+
return subMapOrError.takeError();
3249+
opaqueDecl->setUnderlyingTypeSubstitutions(subMapOrError.get());
3250+
}
32273251
SubstitutionMap subs;
32283252
if (genericSig) {
32293253
subs = genericSig->getIdentitySubstitutionMap();
@@ -5102,7 +5126,11 @@ class TypeDeserializer {
51025126
decls_block::OpaqueArchetypeTypeLayout::readRecord(scratch,
51035127
opaqueDeclID, subsID);
51045128

5105-
auto opaqueDecl = cast<OpaqueTypeDecl>(MF.getDecl(opaqueDeclID));
5129+
auto opaqueTypeOrError = MF.getDeclChecked(opaqueDeclID);
5130+
if (!opaqueTypeOrError)
5131+
return opaqueTypeOrError.takeError();
5132+
5133+
auto opaqueDecl = cast<OpaqueTypeDecl>(opaqueTypeOrError.get());
51065134
auto subs = MF.getSubstitutionMap(subsID);
51075135

51085136
return OpaqueTypeArchetypeType::get(opaqueDecl, subs);
@@ -5827,9 +5855,22 @@ ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
58275855
fatalIfNotSuccess(DeclTypeCursor.JumpToBit(bitPosition));
58285856

58295857
while (numConformances--) {
5830-
auto conf = readConformance(DeclTypeCursor);
5831-
if (conf.isConcrete())
5832-
conformances.push_back(conf.getConcrete());
5858+
auto conformance = readConformanceChecked(DeclTypeCursor);
5859+
5860+
if (!conformance) {
5861+
// Missing module errors are most likely caused by an
5862+
// implementation-only import hiding types and decls.
5863+
// rdar://problem/60291019
5864+
if (conformance.errorIsA<XRefNonLoadedModuleError>()) {
5865+
consumeError(conformance.takeError());
5866+
return;
5867+
}
5868+
else
5869+
fatal(conformance.takeError());
5870+
}
5871+
5872+
if (conformance.get().isConcrete())
5873+
conformances.push_back(conformance.get().getConcrete());
58335874
}
58345875
}
58355876

lib/Serialization/ModuleFile.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -978,13 +978,14 @@ class ModuleFile
978978
llvm::Expected<ProtocolConformanceRef>
979979
readConformanceChecked(llvm::BitstreamCursor &Cursor,
980980
GenericEnvironment *genericEnv = nullptr);
981-
981+
982982
/// Read a SILLayout from the given cursor.
983983
SILLayout *readSILLayout(llvm::BitstreamCursor &Cursor);
984984

985-
/// Read the given normal conformance from the current module file.
986-
NormalProtocolConformance *
987-
readNormalConformance(serialization::NormalConformanceID id);
985+
/// Read the given normal conformance from the current module file,
986+
/// returns the conformance or the first error.
987+
llvm::Expected<NormalProtocolConformance *>
988+
readNormalConformanceChecked(serialization::NormalConformanceID id);
988989

989990
/// Reads a foreign error conformance from \c DeclTypeCursor, if present.
990991
Optional<ForeignErrorConvention> maybeReadForeignErrorConvention();

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
// RUN: %target-swift-frontend -typecheck -DCLIENT_APP -primary-file %s -I %t -index-system-modules -index-store-path %t
1616
// RUN: %target-swift-frontend -emit-sil -DCLIENT_APP -primary-file %s -I %t -module-name client
1717

18+
//// Printing the public module should not crash when checking for overrides of
19+
//// methods from the private module.
20+
// RUN: %target-swift-ide-test -print-module -module-to-print=public_lib -source-filename=x -skip-overrides -I %t
21+
1822
#if PRIVATE_LIB
1923

2024
@propertyWrapper
@@ -38,11 +42,15 @@ public protocol HiddenProtocol {
3842
associatedtype Value
3943
}
4044

45+
public protocol HiddenProtocolWithOverride {
46+
func hiddenOverride()
47+
}
48+
4149
#elseif PUBLIC_LIB
4250

4351
@_implementationOnly import private_lib
4452

45-
struct LibProtocolContraint { }
53+
struct LibProtocolConstraint { }
4654

4755
protocol LibProtocolTABound { }
4856
struct LibProtocolTA: LibProtocolTABound { }
@@ -52,13 +60,13 @@ protocol LibProtocol {
5260

5361
func hiddenRequirement<A>(
5462
param: HiddenGenStruct<A>
55-
) where A.Value == LibProtocolContraint
63+
) where A.Value == LibProtocolConstraint
5664
}
5765

5866
extension LibProtocol where TA == LibProtocolTA {
5967
func hiddenRequirement<A>(
6068
param: HiddenGenStruct<A>
61-
) where A.Value == LibProtocolContraint { }
69+
) where A.Value == LibProtocolConstraint { }
6270
}
6371

6472
public struct PublicStruct: LibProtocol {
@@ -70,6 +78,10 @@ public struct PublicStruct: LibProtocol {
7078
public var wrappedVar: String
7179
}
7280

81+
struct StructWithOverride: HiddenProtocolWithOverride {
82+
func hiddenOverride() {}
83+
}
84+
7385
#elseif CLIENT_APP
7486

7587
import public_lib

0 commit comments

Comments
 (0)