@@ -2801,45 +2801,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
2801
2801
if (ambiguousOverload == solutionDiff.overloads .end ())
2802
2802
return false ;
2803
2803
2804
- ConstraintLocator* commonCalleeLocator = ambiguousOverload->locator ;
2805
- SmallPtrSet<ValueDecl *, 4 > distinctChoices;
2806
- SmallVector<const Solution *, 4 > viableSolutions;
2807
- assert (ambiguousOverload->choices .size () == solutions.size ());
2808
- for (unsigned i = 0 ; i < solutions.size (); ++i) {
2809
- if (distinctChoices.insert (ambiguousOverload->choices [i].getDecl ()).second )
2810
- viableSolutions.push_back (&solutions[i]);
2811
- }
2812
-
2813
- enum class AmbiguityKind {
2814
- // / There is exactly one fix associated with each candidate.
2815
- CloseMatch,
2816
- // / Solution is ambiguous because all candidates had partially matching
2817
- // / parameter lists.
2818
- ParameterList,
2819
- // / General ambiguity failure.
2820
- General,
2821
- // / Argument mismatch ambiguity where each solution has the same
2822
- // / argument mismatch fixes for the same call.
2823
- ArgumentMismatch
2824
- };
2825
- auto ambiguityKind = AmbiguityKind::CloseMatch;
2826
-
2827
- // FIXME: Can this be re-written in a cleaner way?
2828
- for (const auto &solution: solutions) {
2829
- if (solution.Fixes .empty ())
2830
- return false ;
2831
-
2832
- if (solution.Fixes .size () > 1 ) {
2833
- ambiguityKind = (ambiguityKind == AmbiguityKind::CloseMatch ||
2834
- ambiguityKind == AmbiguityKind::ParameterList) &&
2835
- llvm::all_of (solution.Fixes , [](const ConstraintFix *fix) -> bool {
2836
- auto *locator = fix->getLocator ();
2837
- return locator->findLast <LocatorPathElt::ApplyArgument>().hasValue ();
2838
- }) ? AmbiguityKind::ParameterList
2839
- : AmbiguityKind::General;
2840
- }
2841
- }
2842
-
2804
+ auto *commonCalleeLocator = ambiguousOverload->locator ;
2843
2805
auto *decl = ambiguousOverload->choices .front ().getDecl ();
2844
2806
assert (solverState);
2845
2807
@@ -2851,110 +2813,78 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
2851
2813
auto &DE = getASTContext ().Diags ;
2852
2814
auto name = decl->getFullName ();
2853
2815
2854
- auto emitGeneralAmbiguityFailure = [&]() {
2855
- // Three choices here:
2856
- // 1. If this is a special name avoid printing it because
2857
- // printing kind is sufficient;
2858
- // 2. If all of the labels match, print a full name;
2859
- // 3. If labels in different choices are different, it means
2860
- // that we can only print a base name.
2861
- if (name.isSpecial ()) {
2862
- DE.diagnose (commonAnchor->getLoc (),
2863
- diag::no_overloads_match_exactly_in_call_special,
2864
- decl->getDescriptiveKind ());
2865
- } else if (name.isOperator ()) {
2866
- auto operatorId = name.getBaseIdentifier ();
2867
- diagnoseOperatorAmbiguity (*this , operatorId, solutions,
2868
- commonCalleeLocator);
2869
- } else if (llvm::all_of (distinctChoices,
2870
- [&name](const ValueDecl *choice) {
2871
- return choice->getFullName () == name;
2872
- })) {
2873
- DE.diagnose (commonAnchor->getLoc (),
2874
- diag::no_overloads_match_exactly_in_call,
2875
- decl->getDescriptiveKind (), name);
2876
- } else {
2877
- DE.diagnose (commonAnchor->getLoc (),
2878
- diag::no_overloads_match_exactly_in_call_no_labels,
2879
- decl->getDescriptiveKind (), name.getBaseName ());
2880
- }
2881
- };
2816
+ if (name.isOperator ()) {
2817
+ diagnoseOperatorAmbiguity (*this , name.getBaseIdentifier (), solutions,
2818
+ commonCalleeLocator);
2819
+ return true ;
2820
+ }
2882
2821
2883
- switch (ambiguityKind) {
2884
- case AmbiguityKind::ArgumentMismatch:
2885
- case AmbiguityKind::CloseMatch:
2886
- // Handled below
2887
- break ;
2888
- case AmbiguityKind::ParameterList: {
2889
- emitGeneralAmbiguityFailure ();
2822
+ // Emit an error message for the ambiguity.
2823
+ if (aggregatedFixes.size () == 1 &&
2824
+ aggregatedFixes.front ().first .first
2825
+ ->getLastElementAs <LocatorPathElt::ContextualType>()) {
2826
+ auto *anchor = aggregatedFixes.front ().first .first ->getAnchor ();
2827
+ auto baseName = name.getBaseName ();
2828
+ DE.diagnose (commonAnchor->getLoc (), diag::no_candidates_match_result_type,
2829
+ baseName.userFacingName (), getContextualType (anchor));
2830
+ } else if (name.isSpecial ()) {
2831
+ // If this is a special name, avoid printing it because printing the
2832
+ // decl kind is sufficient.
2833
+ DE.diagnose (commonAnchor->getLoc (),
2834
+ diag::no_overloads_match_exactly_in_call_special,
2835
+ decl->getDescriptiveKind ());
2836
+ } else if (llvm::all_of (ambiguousOverload->choices ,
2837
+ [&name](const OverloadChoice &choice) {
2838
+ return choice.getDecl ()->getFullName () == name;
2839
+ })) {
2840
+ // If the labels match in each overload, print a full name.
2841
+ DE.diagnose (commonAnchor->getLoc (),
2842
+ diag::no_overloads_match_exactly_in_call,
2843
+ decl->getDescriptiveKind (), name);
2844
+ } else {
2845
+ // If the labels are different, we can only print a base name.
2846
+ DE.diagnose (commonAnchor->getLoc (),
2847
+ diag::no_overloads_match_exactly_in_call_no_labels,
2848
+ decl->getDescriptiveKind (), name.getBaseName ());
2849
+ }
2850
+
2851
+ // Produce candidate notes
2852
+ SmallPtrSet<ValueDecl *, 4 > distinctChoices;
2853
+ llvm::SmallSet<CanType, 4 > candidateTypes;
2854
+ for (const auto &solution: solutions) {
2855
+ auto overload = solution.getOverloadChoice (commonCalleeLocator);
2856
+ auto *decl = overload.choice .getDecl ();
2857
+ auto type = solution.simplifyType (overload.openedType );
2858
+ // Skip if we've already produced a note for this overload
2859
+ if (!distinctChoices.insert (decl).second )
2860
+ continue ;
2890
2861
2891
- for (const auto &viable: viableSolutions) {
2892
- auto overload = viable->getOverloadChoice (commonCalleeLocator);
2893
- auto *fn = overload.openedType ->getAs <AnyFunctionType>();
2862
+ if (solution.Fixes .size () == 1 ) {
2863
+ // Create scope so each applied solution is rolled back.
2864
+ ConstraintSystem::SolverScope scope (*this );
2865
+ applySolution (solution);
2866
+ // All of the solutions supposed to produce a "candidate" note.
2867
+ diagnosed &= solution.Fixes .front ()->diagnose (/* asNote*/ true );
2868
+ } else if (llvm::all_of (solution.Fixes ,
2869
+ [&](ConstraintFix *fix) {
2870
+ return fix->getLocator ()
2871
+ ->findLast <LocatorPathElt::ApplyArgument>().hasValue ();
2872
+ })) {
2873
+ // All fixes have to do with arguments, so let's show the parameter lists.
2874
+ auto *fn = type->getAs <AnyFunctionType>();
2894
2875
assert (fn);
2895
- DE.diagnose (overload. choice . getDecl () ->getLoc (),
2876
+ DE.diagnose (decl ->getLoc (),
2896
2877
diag::candidate_partial_match,
2897
2878
fn->getParamListAsString (fn->getParams ()));
2898
- }
2899
-
2900
- return true ;
2901
- }
2902
- case AmbiguityKind::General: {
2903
- emitGeneralAmbiguityFailure ();
2904
-
2905
- // Notes for operators are diagnosed through emitGeneralAmbiguityFailure
2906
- if (name.isOperator ())
2907
- return true ;
2908
-
2909
- llvm::SmallSet<CanType, 4 > candidateTypes;
2910
- for (const auto &viable: viableSolutions) {
2911
- auto overload = viable->getOverloadChoice (commonCalleeLocator);
2912
- auto *decl = overload.choice .getDecl ();
2913
- auto type = viable->simplifyType (overload.openedType );
2879
+ } else {
2880
+ // Emit a general "found candidate" note
2914
2881
if (decl->getLoc ().isInvalid ()) {
2915
2882
if (candidateTypes.insert (type->getCanonicalType ()).second )
2916
2883
DE.diagnose (commonAnchor->getLoc (), diag::found_candidate_type, type);
2917
2884
} else {
2918
2885
DE.diagnose (decl->getLoc (), diag::found_candidate);
2919
2886
}
2920
2887
}
2921
-
2922
- return true ;
2923
- }
2924
- }
2925
-
2926
- auto *fix = viableSolutions.front ()->Fixes .front ();
2927
- if (fix->getKind () == FixKind::UseSubscriptOperator) {
2928
- auto *UDE = cast<UnresolvedDotExpr>(commonAnchor);
2929
- DE.diagnose (commonAnchor->getLoc (),
2930
- diag::could_not_find_subscript_member_did_you_mean,
2931
- getType (UDE->getBase ()));
2932
- } else if (fix->getKind () == FixKind::TreatRValueAsLValue) {
2933
- DE.diagnose (commonAnchor->getLoc (),
2934
- diag::no_overloads_match_exactly_in_assignment,
2935
- decl->getBaseName ());
2936
- } else if (llvm::all_of (
2937
- viableSolutions,
2938
- [](const Solution *viable) {
2939
- auto *locator = viable->Fixes .front ()->getLocator ();
2940
- return locator
2941
- ->isLastElement <LocatorPathElt::ContextualType>();
2942
- })) {
2943
- auto anchor =
2944
- viableSolutions.front ()->Fixes .front ()->getLocator ()->getAnchor ();
2945
- auto baseName = name.getBaseName ();
2946
- DE.diagnose (commonAnchor->getLoc (), diag::no_candidates_match_result_type,
2947
- baseName.userFacingName (), getContextualType (anchor));
2948
- } else {
2949
- emitGeneralAmbiguityFailure ();
2950
- }
2951
-
2952
- for (const auto &viable : viableSolutions) {
2953
- // Create scope so each applied solution is rolled back.
2954
- ConstraintSystem::SolverScope scope (*this );
2955
- applySolution (*viable);
2956
- // All of the solutions supposed to produce a "candidate" note.
2957
- diagnosed &= viable->Fixes .front ()->diagnose (/* asNote*/ true );
2958
2888
}
2959
2889
2960
2890
// If not all of the fixes produced a note, we can't diagnose this.
0 commit comments