Skip to content

Commit 97e160b

Browse files
committed
RequirementMachine: Wire up -requirement-machine-inferred-signatures flag
1 parent 163293e commit 97e160b

File tree

1 file changed

+142
-99
lines changed

1 file changed

+142
-99
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 142 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -8649,121 +8649,164 @@ InferredGenericSignatureRequest::evaluate(
86498649
SmallVector<Requirement, 2> addedRequirements,
86508650
SmallVector<TypeLoc, 2> inferenceSources,
86518651
bool allowConcreteGenericParams) const {
8652-
8653-
GenericSignatureBuilder builder(parentModule->getASTContext());
8654-
8655-
// If there is a parent context, add the generic parameters and requirements
8656-
// from that context.
8657-
builder.addGenericSignature(parentSig);
8658-
8659-
DeclContext *lookupDC = nullptr;
8660-
8661-
const auto visitRequirement = [&](const Requirement &req,
8662-
RequirementRepr *reqRepr) {
8663-
const auto source = FloatingRequirementSource::forExplicit(
8664-
reqRepr->getSeparatorLoc());
8665-
8666-
// If we're extending a protocol and adding a redundant requirement,
8667-
// for example, `extension Foo where Self: Foo`, then emit a
8668-
// diagnostic.
8669-
8670-
if (auto decl = lookupDC->getAsDecl()) {
8671-
if (auto extDecl = dyn_cast<ExtensionDecl>(decl)) {
8672-
auto extType = extDecl->getDeclaredInterfaceType();
8673-
auto extSelfType = extDecl->getSelfInterfaceType();
8674-
auto reqLHSType = req.getFirstType();
8675-
auto reqRHSType = req.getSecondType();
8676-
8677-
if (extType->isExistentialType() &&
8678-
reqLHSType->isEqual(extSelfType) &&
8679-
reqRHSType->isEqual(extType)) {
8680-
8681-
auto &ctx = extDecl->getASTContext();
8682-
ctx.Diags.diagnose(extDecl->getLoc(),
8683-
diag::protocol_extension_redundant_requirement,
8684-
extType->getString(),
8685-
extSelfType->getString(),
8686-
reqRHSType->getString());
8652+
auto buildViaGSB = [&]() {
8653+
GenericSignatureBuilder builder(parentModule->getASTContext());
8654+
8655+
// If there is a parent context, add the generic parameters and requirements
8656+
// from that context.
8657+
builder.addGenericSignature(parentSig);
8658+
8659+
DeclContext *lookupDC = nullptr;
8660+
8661+
const auto visitRequirement = [&](const Requirement &req,
8662+
RequirementRepr *reqRepr) {
8663+
const auto source = FloatingRequirementSource::forExplicit(
8664+
reqRepr->getSeparatorLoc());
8665+
8666+
// If we're extending a protocol and adding a redundant requirement,
8667+
// for example, `extension Foo where Self: Foo`, then emit a
8668+
// diagnostic.
8669+
8670+
if (auto decl = lookupDC->getAsDecl()) {
8671+
if (auto extDecl = dyn_cast<ExtensionDecl>(decl)) {
8672+
auto extType = extDecl->getDeclaredInterfaceType();
8673+
auto extSelfType = extDecl->getSelfInterfaceType();
8674+
auto reqLHSType = req.getFirstType();
8675+
auto reqRHSType = req.getSecondType();
8676+
8677+
if (extType->isExistentialType() &&
8678+
reqLHSType->isEqual(extSelfType) &&
8679+
reqRHSType->isEqual(extType)) {
8680+
8681+
auto &ctx = extDecl->getASTContext();
8682+
ctx.Diags.diagnose(extDecl->getLoc(),
8683+
diag::protocol_extension_redundant_requirement,
8684+
extType->getString(),
8685+
extSelfType->getString(),
8686+
reqRHSType->getString());
8687+
}
86878688
}
86888689
}
8690+
8691+
builder.addRequirement(req, reqRepr, source, nullptr,
8692+
lookupDC->getParentModule());
8693+
return false;
8694+
};
8695+
8696+
if (genericParams) {
8697+
// Extensions never have a parent signature.
8698+
if (genericParams->getOuterParameters())
8699+
assert(parentSig == nullptr);
8700+
8701+
// Type check the generic parameters, treating all generic type
8702+
// parameters as dependent, unresolved.
8703+
SmallVector<GenericParamList *, 2> gpLists;
8704+
for (auto *outerParams = genericParams;
8705+
outerParams != nullptr;
8706+
outerParams = outerParams->getOuterParameters()) {
8707+
gpLists.push_back(outerParams);
8708+
}
8709+
8710+
// The generic parameter lists MUST appear from innermost to outermost.
8711+
// We walk them backwards to order outer requirements before
8712+
// inner requirements.
8713+
for (auto &genericParams : llvm::reverse(gpLists)) {
8714+
assert(genericParams->size() > 0 &&
8715+
"Parsed an empty generic parameter list?");
8716+
8717+
// First, add the generic parameters to the generic signature builder.
8718+
// Do this before checking the inheritance clause, since it may
8719+
// itself be dependent on one of these parameters.
8720+
for (const auto param : *genericParams)
8721+
builder.addGenericParameter(param);
8722+
8723+
// Add the requirements for each of the generic parameters to the builder.
8724+
// Now, check the inheritance clauses of each parameter.
8725+
for (const auto param : *genericParams)
8726+
builder.addGenericParameterRequirements(param);
8727+
8728+
// Determine where and how to perform name lookup.
8729+
lookupDC = genericParams->begin()[0]->getDeclContext();
8730+
8731+
// Add the requirements clause to the builder.
8732+
WhereClauseOwner(lookupDC, genericParams)
8733+
.visitRequirements(TypeResolutionStage::Structural,
8734+
visitRequirement);
8735+
}
86898736
}
86908737

8691-
builder.addRequirement(req, reqRepr, source, nullptr,
8692-
lookupDC->getParentModule());
8693-
return false;
8738+
if (whereClause) {
8739+
lookupDC = whereClause.dc;
8740+
std::move(whereClause).visitRequirements(
8741+
TypeResolutionStage::Structural, visitRequirement);
8742+
}
8743+
8744+
/// Perform any remaining requirement inference.
8745+
for (auto sourcePair : inferenceSources) {
8746+
auto *typeRepr = sourcePair.getTypeRepr();
8747+
auto source =
8748+
FloatingRequirementSource::forInferred(
8749+
typeRepr ? typeRepr->getStartLoc() : SourceLoc());
8750+
8751+
builder.inferRequirements(*parentModule,
8752+
sourcePair.getType(),
8753+
source);
8754+
}
8755+
8756+
// Finish by adding any remaining requirements.
8757+
auto source =
8758+
FloatingRequirementSource::forInferred(SourceLoc());
8759+
8760+
for (const auto &req : addedRequirements)
8761+
builder.addRequirement(req, source, parentModule);
8762+
8763+
bool hadError = builder.hadAnyError();
8764+
auto result = std::move(builder).computeGenericSignature(
8765+
allowConcreteGenericParams);
8766+
return GenericSignatureWithError(result, hadError);
86948767
};
86958768

8696-
if (genericParams) {
8697-
// Extensions never have a parent signature.
8698-
if (genericParams->getOuterParameters())
8699-
assert(parentSig == nullptr);
8769+
auto &ctx = parentModule->getASTContext();
87008770

8701-
// Type check the generic parameters, treating all generic type
8702-
// parameters as dependent, unresolved.
8703-
SmallVector<GenericParamList *, 2> gpLists;
8704-
for (auto *outerParams = genericParams;
8705-
outerParams != nullptr;
8706-
outerParams = outerParams->getOuterParameters()) {
8707-
gpLists.push_back(outerParams);
8708-
}
8771+
auto buildViaRQM = [&]() {
8772+
return evaluateOrDefault(
8773+
ctx.evaluator,
8774+
InferredGenericSignatureRequestRQM{
8775+
parentModule,
8776+
parentSig,
8777+
genericParams,
8778+
whereClause,
8779+
addedRequirements,
8780+
inferenceSources,
8781+
allowConcreteGenericParams},
8782+
GenericSignatureWithError());
8783+
};
87098784

8710-
// The generic parameter lists MUST appear from innermost to outermost.
8711-
// We walk them backwards to order outer requirements before
8712-
// inner requirements.
8713-
for (auto &genericParams : llvm::reverse(gpLists)) {
8714-
assert(genericParams->size() > 0 &&
8715-
"Parsed an empty generic parameter list?");
8785+
switch (ctx.LangOpts.RequirementMachineInferredSignatures) {
8786+
case RequirementMachineMode::Disabled:
8787+
return buildViaGSB();
87168788

8717-
// First, add the generic parameters to the generic signature builder.
8718-
// Do this before checking the inheritance clause, since it may
8719-
// itself be dependent on one of these parameters.
8720-
for (const auto param : *genericParams)
8721-
builder.addGenericParameter(param);
8789+
case RequirementMachineMode::Enabled:
8790+
return buildViaRQM();
87228791

8723-
// Add the requirements for each of the generic parameters to the builder.
8724-
// Now, check the inheritance clauses of each parameter.
8725-
for (const auto param : *genericParams)
8726-
builder.addGenericParameterRequirements(param);
8792+
case RequirementMachineMode::Verify: {
8793+
auto rqmResult = buildViaRQM();
8794+
auto gsbResult = buildViaGSB();
87278795

8728-
// Determine where and how to perform name lookup.
8729-
lookupDC = genericParams->begin()[0]->getDeclContext();
8796+
if (!rqmResult.getPointer() && !gsbResult.getPointer())
8797+
return gsbResult;
87308798

8731-
// Add the requirements clause to the builder.
8732-
WhereClauseOwner(lookupDC, genericParams)
8733-
.visitRequirements(TypeResolutionStage::Structural,
8734-
visitRequirement);
8799+
if (!rqmResult.getPointer()->isEqual(gsbResult.getPointer())) {
8800+
llvm::errs() << "RequirementMachine generic signature minimization is broken:\n";
8801+
llvm::errs() << "RequirementMachine says: " << rqmResult.getPointer() << "\n";
8802+
llvm::errs() << "GenericSignatureBuilder says: " << gsbResult.getPointer() << "\n";
8803+
8804+
abort();
87358805
}
8736-
}
87378806

8738-
if (whereClause) {
8739-
lookupDC = whereClause.dc;
8740-
std::move(whereClause).visitRequirements(
8741-
TypeResolutionStage::Structural, visitRequirement);
8807+
return gsbResult;
87428808
}
8743-
8744-
/// Perform any remaining requirement inference.
8745-
for (auto sourcePair : inferenceSources) {
8746-
auto *typeRepr = sourcePair.getTypeRepr();
8747-
auto source =
8748-
FloatingRequirementSource::forInferred(
8749-
typeRepr ? typeRepr->getStartLoc() : SourceLoc());
8750-
8751-
builder.inferRequirements(*parentModule,
8752-
sourcePair.getType(),
8753-
source);
87548809
}
8755-
8756-
// Finish by adding any remaining requirements.
8757-
auto source =
8758-
FloatingRequirementSource::forInferred(SourceLoc());
8759-
8760-
for (const auto &req : addedRequirements)
8761-
builder.addRequirement(req, source, parentModule);
8762-
8763-
bool hadError = builder.hadAnyError();
8764-
auto result = std::move(builder).computeGenericSignature(
8765-
allowConcreteGenericParams);
8766-
return GenericSignatureWithError(result, hadError);
87678810
}
87688811

87698812
ArrayRef<Requirement>

0 commit comments

Comments
 (0)