Skip to content

Commit 593b6c4

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 80f8cfb commit 593b6c4

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
@@ -1005,13 +1005,13 @@ ProtocolConformanceDeserializer::readNormalProtocolConformanceXRef(
10051005
auto error = llvm::make_error<ConformanceXRefError>(
10061006
nominal->getName(), proto->getName(), module);
10071007

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

@@ -8868,23 +8868,27 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
88688868
if (maybeConformance) {
88698869
reqConformances.push_back(maybeConformance.get());
88708870
} else if (getContext().LangOpts.EnableDeserializationRecovery) {
8871-
llvm::Error error = maybeConformance.takeError();
8872-
if (error.isA<ConformanceXRefError>() &&
8873-
!enableExtendedDeserializationRecovery()) {
8871+
// If a conformance is missing, mark the whole protocol conformance
8872+
// as invalid. Something is broken with the context.
8873+
conformance->setInvalid();
88748874

8875+
llvm::Error error = maybeConformance.takeError();
8876+
if (error.isA<ConformanceXRefError>()) {
8877+
// The error was printed along with creating the ConformanceXRefError.
8878+
// Print the note here explaining the side effect.
88758879
std::string typeStr = conformance->getType()->getString();
88768880
auto &diags = getContext().Diags;
88778881
diags.diagnose(getSourceLoc(),
88788882
diag::modularization_issue_conformance_xref_note,
88798883
typeStr, proto->getName());
88808884

88818885
consumeError(std::move(error));
8882-
conformance->setInvalid();
88838886
return;
88848887
}
88858888

8889+
// Leave it up to the centralized service to report other errors.
88868890
diagnoseAndConsumeError(std::move(error));
8887-
reqConformances.push_back(ProtocolConformanceRef::forInvalid());
8891+
return;
88888892
} else {
88898893
fatal(maybeConformance.takeError());
88908894
}

0 commit comments

Comments
 (0)