mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
GSB: Assert that a minimal signature doesn't have protocols refined by other protocols
I'm looking at a bug where we end with a signature like
protocol B { ... }
protocol BB : B { }
<Self where Self : B, Self : BB>
While this one be a one-off bug, it's easy enough to check for this
condition with an assert here.
This commit is contained in:
@@ -7997,6 +7997,9 @@ static void checkGenericSignature(CanGenericSignature canSig,
|
||||
|
||||
auto canonicalRequirements = canSig.getRequirements();
|
||||
|
||||
// We collect conformance requirements to check that they're minimal.
|
||||
llvm::SmallDenseMap<CanType, SmallVector<ProtocolDecl *, 2>, 2> conformances;
|
||||
|
||||
// Check that the signature is canonical.
|
||||
for (unsigned idx : indices(canonicalRequirements)) {
|
||||
debugStack.setRequirement(idx);
|
||||
@@ -8047,6 +8050,10 @@ static void checkGenericSignature(CanGenericSignature canSig,
|
||||
"Left-hand side must be a type parameter");
|
||||
assert(isa<ProtocolType>(reqt.getSecondType().getPointer()) &&
|
||||
"Right-hand side of conformance isn't a protocol type");
|
||||
|
||||
// Collect all conformance requirements on each type parameter.
|
||||
conformances[CanType(reqt.getFirstType())].push_back(
|
||||
reqt.getProtocolDecl());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8089,6 +8096,22 @@ static void checkGenericSignature(CanGenericSignature canSig,
|
||||
assert(prevReqt.compare(reqt) < 0 &&
|
||||
"Out-of-order requirements");
|
||||
}
|
||||
|
||||
// Make sure we don't have redundant protocol conformance requirements.
|
||||
for (auto pair : conformances) {
|
||||
const auto &protos = pair.second;
|
||||
auto canonicalProtos = protos;
|
||||
|
||||
// canonicalizeProtocols() will sort them and filter out any protocols that
|
||||
// are refined by other protocols in the list. It should be a no-op at this
|
||||
// point.
|
||||
ProtocolType::canonicalizeProtocols(canonicalProtos);
|
||||
|
||||
assert(protos.size() == canonicalProtos.size() &&
|
||||
"redundant conformance requirements");
|
||||
assert(std::equal(protos.begin(), protos.end(), canonicalProtos.begin()) &&
|
||||
"out-of-order conformance requirements");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user