@@ -4914,66 +4914,68 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
49144914 // Aggregate all requirement fixes that belong to the same callee
49154915 // and attempt to diagnose possible ambiguities.
49164916 {
4917- auto isResultBuilderRef = [&](ASTNode node) {
4917+ auto isResultBuilderMethodRef = [&](ASTNode node) {
49184918 auto *UDE = getAsExpr<UnresolvedDotExpr>(node);
4919- if (!UDE)
4919+ if (!( UDE && UDE-> isImplicit ()) )
49204920 return false ;
49214921
49224922 auto &ctx = getASTContext ();
4923- return UDE->isImplicit () &&
4924- UDE->getName ().compare (DeclNameRef (ctx.Id_buildBlock )) == 0 ;
4923+ SmallVector<Identifier, 4 > builderMethods (
4924+ {ctx.Id_buildBlock , ctx.Id_buildExpression , ctx.Id_buildPartialBlock ,
4925+ ctx.Id_buildFinalResult });
4926+
4927+ return llvm::any_of (builderMethods, [&](const Identifier &methodId) {
4928+ return UDE->getName ().compare (DeclNameRef (methodId)) == 0 ;
4929+ });
49254930 };
49264931
4927- llvm::MapVector<SourceLoc,
4928- SmallVector<FixInContext, 4 >>
4929- builderFixes;
4932+ // Aggregates fixes fixes attached to `buildExpression` and `buildBlock`
4933+ // methods at the particular source location.
4934+ llvm::MapVector<SourceLoc, SmallVector<FixInContext, 4 >>
4935+ builderMethodRequirementFixes;
49304936
49314937 llvm::MapVector<ConstraintLocator *, SmallVector<FixInContext, 4 >>
4932- requirementFixes ;
4938+ perCalleeRequirementFixes ;
49334939
4934- // TODO(diagnostics): This approach doesn't work for synthesized code
4935- // because i.e. result builders would inject a new `buildBlock` or
4936- // `buildExpression` for every kind of builder. We need to come up
4937- // with the strategy to unify locators in such cases.
49384940 for (const auto &entry : fixes) {
49394941 auto *fix = entry.second ;
49404942 if (!fix->getLocator ()->isLastElement <LocatorPathElt::AnyRequirement>())
49414943 continue ;
49424944
49434945 auto *calleeLoc = entry.first ->getCalleeLocator (fix->getLocator ());
49444946
4945- if (isResultBuilderRef (calleeLoc->getAnchor ())) {
4947+ if (isResultBuilderMethodRef (calleeLoc->getAnchor ())) {
49464948 auto *anchor = castToExpr<Expr>(calleeLoc->getAnchor ());
4947- builderFixes [anchor->getLoc ()].push_back (entry);
4949+ builderMethodRequirementFixes [anchor->getLoc ()].push_back (entry);
49484950 } else {
4949- requirementFixes [calleeLoc].push_back (entry);
4951+ perCalleeRequirementFixes [calleeLoc].push_back (entry);
49504952 }
49514953 }
49524954
4953- SmallVector<FixInContext, 4 > diagnosedFixes;
4955+ SmallVector<SmallVector<FixInContext, 4 >, 4 > viableGroups;
4956+ {
4957+ auto takeAggregateIfViable =
4958+ [&](SmallVector<FixInContext, 4 > &aggregate) {
4959+ // Ambiguity only if all of the solutions have a requirement
4960+ // fix at the given location.
4961+ if (aggregate.size () == solutions.size ())
4962+ viableGroups.push_back (std::move (aggregate));
4963+ };
49544964
4955- for (auto &entry : builderFixes) {
4956- auto &aggregate = entry.second ;
4965+ for (auto &entry : builderMethodRequirementFixes)
4966+ takeAggregateIfViable ( entry.second ) ;
49574967
4958- if ( diagnoseAmbiguityWithGenericRequirements (* this , aggregate) )
4959- diagnosedFixes. append (aggregate. begin (), aggregate. end () );
4968+ for ( auto &entry : perCalleeRequirementFixes )
4969+ takeAggregateIfViable (entry. second );
49604970 }
49614971
4962- for (auto &entry : requirementFixes) {
4963- auto &aggregate = entry.second ;
4964-
4965- // Ambiguity only if all of the solutions have a requirement
4966- // fix at the given location.
4967- if (aggregate.size () != solutions.size ())
4968- continue ;
4969-
4970- if (diagnoseAmbiguityWithGenericRequirements (*this , aggregate))
4971- diagnosedFixes.append (aggregate.begin (), aggregate.end ());
4972+ for (auto &aggregate : viableGroups) {
4973+ if (diagnoseAmbiguityWithGenericRequirements (*this , aggregate)) {
4974+ // Remove diagnosed fixes.
4975+ fixes.set_subtract (aggregate);
4976+ diagnosed = true ;
4977+ }
49724978 }
4973-
4974- diagnosed |= !diagnosedFixes.empty ();
4975- // Remove any diagnosed fixes.
4976- fixes.set_subtract (diagnosedFixes);
49774979 }
49784980
49794981 llvm::MapVector<std::pair<FixKind, ConstraintLocator *>,
0 commit comments