[Conformance checking] Don't suppress substitution failures during checking.

When checking whether a particular protocol conformance satisfies all of
the protocol's requirements, we were suppressing substitution failures.
In some cases, this would mean that we marked a conformance "invalid"
without ever emitting a diagnostic, which would lead to downstream crashes.

Instead, treat substitution failures somewhat more lazily. If we encounter
one while performing the checking, put the conformance into a "delayed" list
rather than failing immediately. Teach the top-level type checking
loop to re-check these conformances, emitting a diagnostic if they
fail the second time around.

Fixes rdar://problem/35082483 and likely other issues that slipped
through the type checker or blew up in unpredictable ways.
This commit is contained in:
Doug Gregor
2017-12-18 16:33:33 -08:00
parent 607a0ddffb
commit d9095b1079
7 changed files with 111 additions and 23 deletions

View File

@@ -387,6 +387,11 @@ void NormalProtocolConformance::differenceAndStoreConditionalRequirements() {
void NormalProtocolConformance::setSignatureConformances(
ArrayRef<ProtocolConformanceRef> conformances) {
if (conformances.empty()) {
SignatureConformances = { };
return;
}
auto &ctx = getProtocol()->getASTContext();
SignatureConformances = ctx.AllocateCopy(conformances);
@@ -460,11 +465,6 @@ NormalProtocolConformance::populateSignatureConformances() {
other.owning = false;
}
~Writer() {
assert((!owning || self->isInvalid() || requirementSignature.empty()) &&
"signature conformances were not fully populated");
}
void operator()(ProtocolConformanceRef conformance){
// Make sure we have the right conformance.
assert(!requirementSignature.empty() && "Too many conformances?");