Skip to content

Commit 1d035f2

Browse files
committed
Serialization: Align conformance recovery logic across modes
Always give up early when attempting to deserialize a protocol conformance broken by a context change. Don't attempt to replace missing members of the conformance signature with invalid one, just mark the whole protocol conformance as invalid. The previous recovery logic, only for SourceKit mode and LLDB, was inserting invalid conformances in the signature instead of dropping the whole protocol conformance. It lead to failures later in the same `finishNormalConformance` when accessing the invalid conformances. rdar://98925842
1 parent dbedb21 commit 1d035f2

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,13 +1006,13 @@ ProtocolConformanceDeserializer::readNormalProtocolConformanceXRef(
10061006
auto error = llvm::make_error<ConformanceXRefError>(
10071007
nominal->getName(), proto->getName(), module);
10081008

1009-
if (!MF.enableExtendedDeserializationRecovery()) {
1010-
error = llvm::handleErrors(std::move(error),
1011-
[&](const ConformanceXRefError &error) -> llvm::Error {
1012-
error.diagnose(&MF);
1013-
return llvm::make_error<ConformanceXRefError>(std::move(error));
1014-
});
1015-
}
1009+
// Diagnose the root error here.
1010+
error = llvm::handleErrors(std::move(error),
1011+
[&](const ConformanceXRefError &error) -> llvm::Error {
1012+
error.diagnose(&MF);
1013+
return llvm::make_error<ConformanceXRefError>(std::move(error));
1014+
});
1015+
10161016
return error;
10171017
}
10181018

@@ -8899,23 +8899,27 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
88998899
if (maybeConformance) {
89008900
reqConformances.push_back(maybeConformance.get());
89018901
} else if (getContext().LangOpts.EnableDeserializationRecovery) {
8902-
llvm::Error error = maybeConformance.takeError();
8903-
if (error.isA<ConformanceXRefError>() &&
8904-
!enableExtendedDeserializationRecovery()) {
8902+
// If a conformance is missing, mark the whole protocol conformance
8903+
// as invalid. Something is broken with the context.
8904+
conformance->setInvalid();
89058905

8906+
llvm::Error error = maybeConformance.takeError();
8907+
if (error.isA<ConformanceXRefError>()) {
8908+
// The error was printed along with creating the ConformanceXRefError.
8909+
// Print the note here explaining the side effect.
89068910
std::string typeStr = conformance->getType()->getString();
89078911
auto &diags = getContext().Diags;
89088912
diags.diagnose(getSourceLoc(),
89098913
diag::modularization_issue_conformance_xref_note,
89108914
typeStr, proto->getName());
89118915

89128916
consumeError(std::move(error));
8913-
conformance->setInvalid();
89148917
return;
89158918
}
89168919

8920+
// Leave it up to the centralized service to report other errors.
89178921
diagnoseAndConsumeError(std::move(error));
8918-
reqConformances.push_back(ProtocolConformanceRef::forInvalid());
8922+
return;
89198923
} else {
89208924
fatal(maybeConformance.takeError());
89218925
}

0 commit comments

Comments
 (0)