Skip to content

Commit 0eb6622

Browse files
committed
AST: Move expensive generic signature checks to GenericSignature.cpp
This removes the final dependency on GenericSignatureBuilder.h.
1 parent 25ac1f5 commit 0eb6622

File tree

5 files changed

+124
-125
lines changed

5 files changed

+124
-125
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,16 @@ int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
496496

497497
int compareDependentTypes(Type type1, Type type2);
498498

499+
/// Verify the correctness of the given generic signature.
500+
///
501+
/// This routine will test that the given generic signature is both minimal
502+
/// and canonical, emitting errors if it is not.
503+
void validateGenericSignature(ASTContext &context,
504+
GenericSignature sig);
505+
506+
/// Verify all of the generic signatures in the given module.
507+
void validateGenericSignaturesInModule(ModuleDecl *module);
508+
499509
/// Build a generic signature from the given requirements, which are not
500510
/// required to be minimal or canonical, and may contain unresolved
501511
/// DependentMemberTypes.

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -802,16 +802,6 @@ class GenericSignatureBuilder {
802802
ProtocolDecl *protocol,
803803
GenericSignature sig);
804804

805-
/// Verify the correctness of the given generic signature.
806-
///
807-
/// This routine will test that the given generic signature is both minimal
808-
/// and canonical, emitting errors if it is not.
809-
static void verifyGenericSignature(ASTContext &context,
810-
GenericSignature sig);
811-
812-
/// Verify all of the generic sigantures in the given module.
813-
static void verifyGenericSignaturesInModule(ModuleDecl *module);
814-
815805
/// Dump all of the requirements, both specified and inferred. It cannot be
816806
/// statically proven that this doesn't modify the GSB.
817807
SWIFT_DEBUG_HELPER(void dump());

lib/AST/GenericSignature.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,8 @@ int swift::compareDependentTypes(Type type1, Type type2) {
15611561
return 0;
15621562
}
15631563

1564+
#pragma mark Generic signature verification
1565+
15641566
void GenericSignature::verify() const {
15651567
auto canSig = getCanonicalSignature();
15661568

@@ -1738,6 +1740,116 @@ void GenericSignature::verify() const {
17381740
}
17391741
}
17401742

1743+
void swift::validateGenericSignature(ASTContext &context,
1744+
GenericSignature sig) {
1745+
llvm::errs() << "Validating generic signature: ";
1746+
sig->print(llvm::errs());
1747+
llvm::errs() << "\n";
1748+
1749+
// Try building a new signature having the same requirements.
1750+
SmallVector<GenericTypeParamType *, 2> genericParams;
1751+
for (auto *genericParam : sig.getGenericParams())
1752+
genericParams.push_back(genericParam);
1753+
1754+
SmallVector<Requirement, 2> requirements;
1755+
for (auto requirement : sig.getRequirements())
1756+
requirements.push_back(requirement);
1757+
1758+
{
1759+
PrettyStackTraceGenericSignature debugStack("verifying", sig);
1760+
1761+
auto newSigWithError = evaluateOrDefault(
1762+
context.evaluator,
1763+
AbstractGenericSignatureRequest{
1764+
nullptr,
1765+
genericParams,
1766+
requirements},
1767+
GenericSignatureWithError());
1768+
1769+
// If there were any errors, the signature was invalid.
1770+
if (newSigWithError.getInt()) {
1771+
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_valid,
1772+
sig->getAsString());
1773+
}
1774+
1775+
auto newSig = newSigWithError.getPointer();
1776+
1777+
// The new signature should be equal.
1778+
if (!newSig->isEqual(sig)) {
1779+
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_equal,
1780+
sig->getAsString(), newSig->getAsString());
1781+
}
1782+
}
1783+
1784+
// Try removing each requirement in turn.
1785+
for (unsigned victimIndex : indices(requirements)) {
1786+
PrettyStackTraceGenericSignature debugStack("verifying", sig, victimIndex);
1787+
1788+
// Add the requirements *except* the victim.
1789+
SmallVector<Requirement, 2> newRequirements;
1790+
for (unsigned i : indices(requirements)) {
1791+
if (i != victimIndex)
1792+
newRequirements.push_back(requirements[i]);
1793+
}
1794+
1795+
auto newSigWithError = evaluateOrDefault(
1796+
context.evaluator,
1797+
AbstractGenericSignatureRequest{
1798+
nullptr,
1799+
genericParams,
1800+
newRequirements},
1801+
GenericSignatureWithError());
1802+
1803+
// If there were any errors, we formed an invalid signature, so
1804+
// just continue.
1805+
if (newSigWithError.getInt())
1806+
continue;
1807+
1808+
auto newSig = newSigWithError.getPointer();
1809+
1810+
// If the new signature once again contains the removed requirement, it's
1811+
// not redundant.
1812+
if (newSig->isEqual(sig))
1813+
continue;
1814+
1815+
// If the removed requirement is satisfied by the new generic signature,
1816+
// it is redundant. Complain.
1817+
if (newSig->isRequirementSatisfied(requirements[victimIndex])) {
1818+
SmallString<32> reqString;
1819+
{
1820+
llvm::raw_svector_ostream out(reqString);
1821+
requirements[victimIndex].print(out, PrintOptions());
1822+
}
1823+
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_minimal,
1824+
reqString, sig->getAsString());
1825+
}
1826+
}
1827+
}
1828+
1829+
void swift::validateGenericSignaturesInModule(ModuleDecl *module) {
1830+
LoadedFile *loadedFile = nullptr;
1831+
for (auto fileUnit : module->getFiles()) {
1832+
loadedFile = dyn_cast<LoadedFile>(fileUnit);
1833+
if (loadedFile) break;
1834+
}
1835+
1836+
if (!loadedFile) return;
1837+
1838+
// Check all of the (canonical) generic signatures.
1839+
SmallVector<GenericSignature, 8> allGenericSignatures;
1840+
SmallPtrSet<CanGenericSignature, 4> knownGenericSignatures;
1841+
(void)loadedFile->getAllGenericSignatures(allGenericSignatures);
1842+
ASTContext &context = module->getASTContext();
1843+
for (auto genericSig : allGenericSignatures) {
1844+
// Check whether this is the first time we've checked this (canonical)
1845+
// signature.
1846+
auto canGenericSig = genericSig.getCanonicalSignature();
1847+
if (!knownGenericSignatures.insert(canGenericSig).second) continue;
1848+
1849+
validateGenericSignature(context, canGenericSig);
1850+
}
1851+
}
1852+
17411853
GenericSignature
17421854
swift::buildGenericSignature(ASTContext &ctx,
17431855
GenericSignature baseSignature,

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 0 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -8444,119 +8444,6 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
84448444
return sig;
84458445
}
84468446

8447-
#pragma mark Generic signature verification
8448-
8449-
void GenericSignatureBuilder::verifyGenericSignature(ASTContext &context,
8450-
GenericSignature sig) {
8451-
llvm::errs() << "Validating generic signature: ";
8452-
sig->print(llvm::errs());
8453-
llvm::errs() << "\n";
8454-
8455-
// Try building a new signature having the same requirements.
8456-
SmallVector<GenericTypeParamType *, 2> genericParams;
8457-
for (auto *genericParam : sig.getGenericParams())
8458-
genericParams.push_back(genericParam);
8459-
8460-
SmallVector<Requirement, 2> requirements;
8461-
for (auto requirement : sig.getRequirements())
8462-
requirements.push_back(requirement);
8463-
8464-
{
8465-
PrettyStackTraceGenericSignature debugStack("verifying", sig);
8466-
8467-
auto newSigWithError = evaluateOrDefault(
8468-
context.evaluator,
8469-
AbstractGenericSignatureRequest{
8470-
nullptr,
8471-
genericParams,
8472-
requirements},
8473-
GenericSignatureWithError());
8474-
8475-
// If there were any errors, the signature was invalid.
8476-
if (newSigWithError.getInt()) {
8477-
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_valid,
8478-
sig->getAsString());
8479-
}
8480-
8481-
auto newSig = newSigWithError.getPointer();
8482-
8483-
// The new signature should be equal.
8484-
if (!newSig->isEqual(sig)) {
8485-
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_equal,
8486-
sig->getAsString(), newSig->getAsString());
8487-
}
8488-
}
8489-
8490-
// Try removing each requirement in turn.
8491-
for (unsigned victimIndex : indices(requirements)) {
8492-
PrettyStackTraceGenericSignature debugStack("verifying", sig, victimIndex);
8493-
8494-
// Add the requirements *except* the victim.
8495-
SmallVector<Requirement, 2> newRequirements;
8496-
for (unsigned i : indices(requirements)) {
8497-
if (i != victimIndex)
8498-
newRequirements.push_back(requirements[i]);
8499-
}
8500-
8501-
auto newSigWithError = evaluateOrDefault(
8502-
context.evaluator,
8503-
AbstractGenericSignatureRequest{
8504-
nullptr,
8505-
genericParams,
8506-
newRequirements},
8507-
GenericSignatureWithError());
8508-
8509-
// If there were any errors, we formed an invalid signature, so
8510-
// just continue.
8511-
if (newSigWithError.getInt())
8512-
continue;
8513-
8514-
auto newSig = newSigWithError.getPointer();
8515-
8516-
// If the new signature once again contains the removed requirement, it's
8517-
// not redundant.
8518-
if (newSig->isEqual(sig))
8519-
continue;
8520-
8521-
// If the removed requirement is satisfied by the new generic signature,
8522-
// it is redundant. Complain.
8523-
if (newSig->isRequirementSatisfied(requirements[victimIndex])) {
8524-
SmallString<32> reqString;
8525-
{
8526-
llvm::raw_svector_ostream out(reqString);
8527-
requirements[victimIndex].print(out, PrintOptions());
8528-
}
8529-
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_minimal,
8530-
reqString, sig->getAsString());
8531-
}
8532-
}
8533-
}
8534-
8535-
void GenericSignatureBuilder::verifyGenericSignaturesInModule(
8536-
ModuleDecl *module) {
8537-
LoadedFile *loadedFile = nullptr;
8538-
for (auto fileUnit : module->getFiles()) {
8539-
loadedFile = dyn_cast<LoadedFile>(fileUnit);
8540-
if (loadedFile) break;
8541-
}
8542-
8543-
if (!loadedFile) return;
8544-
8545-
// Check all of the (canonical) generic signatures.
8546-
SmallVector<GenericSignature, 8> allGenericSignatures;
8547-
SmallPtrSet<CanGenericSignature, 4> knownGenericSignatures;
8548-
(void)loadedFile->getAllGenericSignatures(allGenericSignatures);
8549-
ASTContext &context = module->getASTContext();
8550-
for (auto genericSig : allGenericSignatures) {
8551-
// Check whether this is the first time we've checked this (canonical)
8552-
// signature.
8553-
auto canGenericSig = genericSig.getCanonicalSignature();
8554-
if (!knownGenericSignatures.insert(canGenericSig).second) continue;
8555-
8556-
verifyGenericSignature(context, canGenericSig);
8557-
}
8558-
}
8559-
85608447
/// Check whether the inputs to the \c AbstractGenericSignatureRequest are
85618448
/// all canonical.
85628449
static bool isCanonicalRequest(GenericSignature baseSignature,

lib/FrontendTool/FrontendTool.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include "swift/AST/FileSystem.h"
3131
#include "swift/AST/FineGrainedDependencies.h"
3232
#include "swift/AST/FineGrainedDependencyFormat.h"
33-
#include "swift/AST/GenericSignatureBuilder.h"
33+
#include "swift/AST/GenericSignature.h"
3434
#include "swift/AST/IRGenOptions.h"
3535
#include "swift/AST/IRGenRequests.h"
3636
#include "swift/AST/NameLookup.h"
@@ -469,7 +469,7 @@ static void verifyGenericSignaturesIfNeeded(const FrontendOptions &opts,
469469
if (verifyGenericSignaturesInModule.empty())
470470
return;
471471
if (auto module = Context.getModuleByName(verifyGenericSignaturesInModule))
472-
GenericSignatureBuilder::verifyGenericSignaturesInModule(module);
472+
swift::validateGenericSignaturesInModule(module);
473473
}
474474

475475
static bool dumpAndPrintScopeMap(const CompilerInstance &Instance,

0 commit comments

Comments
 (0)