@@ -179,6 +179,8 @@ const char ModularizationError::ID = '\0';
179
179
void ModularizationError::anchor () {}
180
180
const char InvalidEnumValueError::ID = ' \0 ' ;
181
181
void InvalidEnumValueError::anchor () {}
182
+ const char ConformanceXRefError::ID = ' \0 ' ;
183
+ void ConformanceXRefError::anchor () {}
182
184
183
185
// / Skips a single record in the bitstream.
184
186
// /
@@ -404,6 +406,16 @@ ModuleFile::diagnoseModularizationError(llvm::Error error,
404
406
return outError;
405
407
}
406
408
409
+ void
410
+ ConformanceXRefError::diagnose (const ModuleFile *MF,
411
+ DiagnosticBehavior limit) const {
412
+ auto &diags = MF->getContext ().Diags ;
413
+ diags.diagnose (MF->getSourceLoc (),
414
+ diag::modularization_issue_conformance_xref_error,
415
+ name, protoName, expectedModule->getName ())
416
+ .limitBehavior (limit);
417
+ }
418
+
407
419
llvm::Error ModuleFile::diagnoseFatal (llvm::Error error) const {
408
420
409
421
auto &ctx = getContext ();
@@ -860,7 +872,8 @@ ProtocolConformanceDeserializer::readSpecializedProtocolConformance(
860
872
return subMapOrError.takeError ();
861
873
auto subMap = subMapOrError.get ();
862
874
863
- auto genericConformance = MF.getConformance (conformanceID);
875
+ ProtocolConformanceRef genericConformance;
876
+ UNWRAP (MF.getConformanceChecked (conformanceID), genericConformance);
864
877
865
878
PrettyStackTraceDecl traceTo (" ... to" , genericConformance.getRequirement ());
866
879
++NumNormalProtocolConformancesLoaded;
@@ -892,8 +905,8 @@ ProtocolConformanceDeserializer::readInheritedProtocolConformance(
892
905
PrettyStackTraceType trace (ctx, " reading inherited conformance for" ,
893
906
conformingType);
894
907
895
- ProtocolConformanceRef inheritedConformance =
896
- MF.getConformance (conformanceID);
908
+ ProtocolConformanceRef inheritedConformance;
909
+ UNWRAP ( MF.getConformanceChecked (conformanceID), inheritedConformance );
897
910
PrettyStackTraceDecl traceTo (" ... to" ,
898
911
inheritedConformance.getRequirement ());
899
912
@@ -943,14 +956,16 @@ ProtocolConformanceDeserializer::readNormalProtocolConformanceXRef(
943
956
ProtocolConformanceXrefLayout::readRecord (scratch, protoID, nominalID,
944
957
moduleID);
945
958
946
- auto maybeNominal = MF.getDeclChecked (nominalID);
947
- if (!maybeNominal)
948
- return maybeNominal.takeError ();
949
-
950
- auto nominal = cast<NominalTypeDecl>(maybeNominal.get ());
959
+ Decl *maybeNominal;
960
+ UNWRAP (MF.getDeclChecked (nominalID), maybeNominal);
961
+ auto nominal = cast<NominalTypeDecl>(maybeNominal);
951
962
PrettyStackTraceDecl trace (" cross-referencing conformance for" , nominal);
952
- auto proto = cast<ProtocolDecl>(MF.getDecl (protoID));
963
+
964
+ Decl *maybeProto;
965
+ UNWRAP (MF.getDeclChecked (protoID), maybeProto);
966
+ auto proto = cast<ProtocolDecl>(maybeProto);
953
967
PrettyStackTraceDecl traceTo (" ... to" , proto);
968
+
954
969
auto module = MF.getModule (moduleID);
955
970
956
971
// FIXME: If the module hasn't been loaded, we probably don't want to fall
@@ -971,16 +986,26 @@ ProtocolConformanceDeserializer::readNormalProtocolConformanceXRef(
971
986
// TODO: Sink Sendable derivation into the conformance lookup table
972
987
if (proto->isSpecificProtocol (KnownProtocolKind::Sendable)) {
973
988
auto conformanceRef = lookupConformance (nominal->getDeclaredInterfaceType (), proto);
974
- if (!conformanceRef.isConcrete ())
975
- abort ();
976
- return conformanceRef.getConcrete ();
989
+ if (conformanceRef.isConcrete ())
990
+ return conformanceRef.getConcrete ();
977
991
} else {
978
992
SmallVector<ProtocolConformance *, 2 > conformances;
979
993
nominal->lookupConformance (proto, conformances);
980
- if (conformances.empty ())
981
- abort ();
982
- return conformances.front ();
994
+ if (!conformances.empty ())
995
+ return conformances.front ();
983
996
}
997
+
998
+ auto error = llvm::make_error<ConformanceXRefError>(
999
+ nominal->getName (), proto->getName (), module );
1000
+
1001
+ if (!MF.enableExtendedDeserializationRecovery ()) {
1002
+ error = llvm::handleErrors (std::move (error),
1003
+ [&](const ConformanceXRefError &error) -> llvm::Error {
1004
+ error.diagnose (&MF);
1005
+ return llvm::make_error<ConformanceXRefError>(std::move (error));
1006
+ });
1007
+ }
1008
+ return error;
984
1009
}
985
1010
986
1011
Expected<ProtocolConformance *>
@@ -7863,7 +7888,7 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
7863
7888
ProtocolConformanceRef witnessMethodConformance;
7864
7889
if (*representation == swift::SILFunctionTypeRepresentation::WitnessMethod) {
7865
7890
auto conformanceID = variableData[nextVariableDataIndex++];
7866
- witnessMethodConformance = MF.getConformance (conformanceID);
7891
+ UNWRAP ( MF.getConformanceChecked (conformanceID), witnessMethodConformance );
7867
7892
}
7868
7893
7869
7894
GenericSignature invocationSig =
@@ -8643,21 +8668,37 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
8643
8668
scratch, protoID, contextID, typeCount, valueCount, conformanceCount,
8644
8669
rawOptions, rawIDs);
8645
8670
8671
+ const ProtocolDecl *proto = conformance->getProtocol ();
8672
+
8646
8673
// Read requirement signature conformances.
8647
8674
SmallVector<ProtocolConformanceRef, 4 > reqConformances;
8648
8675
for (auto conformanceID : rawIDs.slice (0 , conformanceCount)) {
8649
8676
auto maybeConformance = getConformanceChecked (conformanceID);
8650
8677
if (maybeConformance) {
8651
8678
reqConformances.push_back (maybeConformance.get ());
8652
8679
} else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
8653
- diagnoseAndConsumeError (maybeConformance.takeError ());
8680
+ llvm::Error error = maybeConformance.takeError ();
8681
+ if (error.isA <ConformanceXRefError>() &&
8682
+ !enableExtendedDeserializationRecovery ()) {
8683
+
8684
+ std::string typeStr = conformance->getType ()->getString ();
8685
+ auto &diags = getContext ().Diags ;
8686
+ diags.diagnose (getSourceLoc (),
8687
+ diag::modularization_issue_conformance_xref_note,
8688
+ typeStr, proto->getName ());
8689
+
8690
+ consumeError (std::move (error));
8691
+ conformance->setInvalid ();
8692
+ return ;
8693
+ }
8694
+
8695
+ diagnoseAndConsumeError (std::move (error));
8654
8696
reqConformances.push_back (ProtocolConformanceRef::forInvalid ());
8655
8697
} else {
8656
8698
fatal (maybeConformance.takeError ());
8657
8699
}
8658
8700
}
8659
8701
8660
- const ProtocolDecl *proto = conformance->getProtocol ();
8661
8702
if (proto->isObjC () && getContext ().LangOpts .EnableDeserializationRecovery ) {
8662
8703
// Don't crash if inherited protocols are added or removed.
8663
8704
// This is limited to Objective-C protocols because we know their only
0 commit comments