@@ -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
87698812ArrayRef<Requirement>
0 commit comments