@@ -2765,6 +2765,9 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
2765
2765
ParameterList,
2766
2766
// / General ambiguity failure.
2767
2767
General,
2768
+ // / Argument mismatch ambiguity where each solution has the same
2769
+ // / argument mismatch fixes for the same call.
2770
+ ArgumentMismatch
2768
2771
};
2769
2772
auto ambiguityKind = AmbiguityKind::CloseMatch;
2770
2773
@@ -2775,16 +2778,52 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
2775
2778
return false ;
2776
2779
2777
2780
if (fixes.size () > 1 ) {
2778
- ambiguityKind = (ambiguityKind == AmbiguityKind::CloseMatch ||
2779
- ambiguityKind == AmbiguityKind::ParameterList) &&
2781
+ // Attempt to disambiguite in cases where the argument matches
2782
+ // involves tuple mismatches. e.g.
2783
+ // func t<T, U>(_: (T, U), _: (U, T)) {}
2784
+ // func useTuples(_ x: Int, y: Float) {
2785
+ // t((x, y), (x, y))
2786
+ // }
2787
+ // So fixes are ambiguous in all solutions.
2788
+ if ((ambiguityKind == AmbiguityKind::CloseMatch ||
2789
+ ambiguityKind == AmbiguityKind::ArgumentMismatch) &&
2780
2790
llvm::all_of (fixes, [](const ConstraintFix *fix) -> bool {
2781
- auto *locator = fix->getLocator ();
2782
- return locator->findLast <LocatorPathElt::ApplyArgument>().hasValue ();
2783
- }) ? AmbiguityKind::ParameterList
2784
- : AmbiguityKind::General;
2791
+ return fix->getKind () == FixKind::AllowTupleTypeMismatch;
2792
+ })) {
2793
+ ambiguityKind = AmbiguityKind::ArgumentMismatch;
2794
+ } else {
2795
+ ambiguityKind =
2796
+ (ambiguityKind == AmbiguityKind::CloseMatch ||
2797
+ ambiguityKind == AmbiguityKind::ArgumentMismatch ||
2798
+ ambiguityKind == AmbiguityKind::ParameterList) &&
2799
+ llvm::all_of (
2800
+ fixes,
2801
+ [](const ConstraintFix *fix) -> bool {
2802
+ auto *locator = fix->getLocator ();
2803
+ return locator
2804
+ ->findLast <LocatorPathElt::ApplyArgument>()
2805
+ .hasValue ();
2806
+ })
2807
+ ? AmbiguityKind::ParameterList
2808
+ : AmbiguityKind::General;
2809
+ }
2810
+ }
2811
+
2812
+ if (fixes.size () == 1 ) {
2813
+ // Attempt to disambiguite in cases where all the solutions
2814
+ // produces the same fixes for diferent generic arguments e.g.
2815
+ // func f<T>(_: T, _: T) {}
2816
+ // f(Int(1), Float(1))
2817
+ //
2818
+ ambiguityKind =
2819
+ ((ambiguityKind == AmbiguityKind::CloseMatch ||
2820
+ ambiguityKind == AmbiguityKind::ArgumentMismatch) &&
2821
+ fixes.front ()->getKind () == FixKind::AllowArgumentTypeMismatch)
2822
+ ? AmbiguityKind::ArgumentMismatch
2823
+ : AmbiguityKind::CloseMatch;
2785
2824
}
2786
2825
2787
- for (const auto *fix: fixes) {
2826
+ for (const auto *fix : fixes) {
2788
2827
auto *locator = fix->getLocator ();
2789
2828
// Assignment failures are all about the source expression,
2790
2829
// because they treat destination as a contextual type.
@@ -2816,6 +2855,15 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
2816
2855
return true ;
2817
2856
});
2818
2857
2858
+ if (ambiguityKind == AmbiguityKind::ArgumentMismatch &&
2859
+ viableSolutions.size () == 1 ) {
2860
+ // Let's apply the solution so the contextual generic types
2861
+ // are available in the system for diagnostics.
2862
+ applySolution (*viableSolutions[0 ]);
2863
+ solutions.front ().Fixes .front ()->diagnose (/* asNote*/ false );
2864
+ return true ;
2865
+ }
2866
+
2819
2867
if (!diagnosable || viableSolutions.size () < 2 )
2820
2868
return false ;
2821
2869
@@ -2860,6 +2908,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
2860
2908
};
2861
2909
2862
2910
switch (ambiguityKind) {
2911
+ case AmbiguityKind::ArgumentMismatch:
2863
2912
case AmbiguityKind::CloseMatch:
2864
2913
// Handled below
2865
2914
break ;
0 commit comments