@@ -2778,45 +2778,61 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
2778
2778
2779
2779
auto &DE = cs.getASTContext ().Diags ;
2780
2780
2781
- llvm::SmallDenseMap<TypeVariableType *, SmallVector<Type, 4 >> conflicts;
2781
+ llvm::SmallDenseMap<TypeVariableType *,
2782
+ std::pair<GenericTypeParamType *, SourceLoc>, 4 >
2783
+ genericParams;
2784
+ // Consider only representative type variables shared across
2785
+ // all of the solutions.
2786
+ for (auto *typeVar : cs.getTypeVariables ()) {
2787
+ if (auto *GP = typeVar->getImpl ().getGenericParameter ()) {
2788
+ auto *locator = typeVar->getImpl ().getLocator ();
2789
+ auto *repr = cs.getRepresentative (typeVar);
2790
+ // If representative is another generic parameter let's
2791
+ // use its generic parameter type instead of originator's,
2792
+ // but it's possible that generic parameter is equated to
2793
+ // some other type e.g.
2794
+ //
2795
+ // func foo<T>(_: T) -> T {}
2796
+ //
2797
+ // In this case when reference to function `foo` is "opened"
2798
+ // type variable representing `T` would be equated to
2799
+ // type variable representing a result type of the reference.
2800
+ if (auto *reprGP = repr->getImpl ().getGenericParameter ())
2801
+ GP = reprGP;
2802
+
2803
+ genericParams[repr] = {GP, locator->getAnchor ()->getLoc ()};
2804
+ }
2805
+ }
2782
2806
2783
- for (const auto &binding : solutions[0 ].typeBindings ) {
2784
- auto *typeVar = binding.first ;
2807
+ llvm::SmallDenseMap<std::pair<GenericTypeParamType *, SourceLoc>,
2808
+ SmallVector<Type, 4 >>
2809
+ conflicts;
2785
2810
2786
- if (!typeVar->getImpl ().getGenericParameter ())
2787
- continue ;
2811
+ for (const auto &entry : genericParams) {
2812
+ auto *typeVar = entry.first ;
2813
+ auto GP = entry.second ;
2788
2814
2789
2815
llvm::SmallSetVector<Type, 4 > arguments;
2790
- arguments.insert (binding.second );
2791
-
2792
- if (!llvm::all_of (solutions.slice (1 ), [&](const Solution &solution) {
2793
- auto binding = solution.typeBindings .find (typeVar);
2794
- if (binding == solution.typeBindings .end ())
2795
- return false ;
2796
-
2797
- // Contextual opaque result type is uniquely identified by
2798
- // declaration it's associated with, so we have to compare
2799
- // declarations instead of using pointer equality on such types.
2800
- if (auto *opaque =
2801
- binding->second ->getAs <OpaqueTypeArchetypeType>()) {
2802
- auto *decl = opaque->getDecl ();
2803
- arguments.remove_if ([&](Type argType) -> bool {
2804
- if (auto *otherOpaque =
2805
- argType->getAs <OpaqueTypeArchetypeType>()) {
2806
- return decl == otherOpaque->getDecl ();
2807
- }
2808
- return false ;
2809
- });
2816
+ for (const auto &solution : solutions) {
2817
+ auto type = solution.typeBindings .lookup (typeVar);
2818
+ // Contextual opaque result type is uniquely identified by
2819
+ // declaration it's associated with, so we have to compare
2820
+ // declarations instead of using pointer equality on such types.
2821
+ if (auto *opaque = type->getAs <OpaqueTypeArchetypeType>()) {
2822
+ auto *decl = opaque->getDecl ();
2823
+ arguments.remove_if ([&](Type argType) -> bool {
2824
+ if (auto *otherOpaque = argType->getAs <OpaqueTypeArchetypeType>()) {
2825
+ return decl == otherOpaque->getDecl ();
2810
2826
}
2827
+ return false ;
2828
+ });
2829
+ }
2811
2830
2812
- arguments.insert (binding->second );
2813
- return true ;
2814
- }))
2815
- continue ;
2816
-
2817
- if (arguments.size () > 1 ) {
2818
- conflicts[typeVar].append (arguments.begin (), arguments.end ());
2831
+ arguments.insert (type);
2819
2832
}
2833
+
2834
+ if (arguments.size () > 1 )
2835
+ conflicts[GP].append (arguments.begin (), arguments.end ());
2820
2836
}
2821
2837
2822
2838
auto getGenericTypeDecl = [&](ArchetypeType *archetype) -> ValueDecl * {
@@ -2833,8 +2849,10 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
2833
2849
2834
2850
bool diagnosed = false ;
2835
2851
for (auto &conflict : conflicts) {
2836
- auto *typeVar = conflict.first ;
2837
- auto *locator = typeVar->getImpl ().getLocator ();
2852
+ SourceLoc loc;
2853
+ GenericTypeParamType *GP;
2854
+
2855
+ std::tie (GP, loc) = conflict.first ;
2838
2856
auto conflictingArguments = conflict.second ;
2839
2857
2840
2858
llvm::SmallString<64 > arguments;
@@ -2859,10 +2877,8 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
2859
2877
},
2860
2878
[&OS] { OS << " vs. " ; });
2861
2879
2862
- auto *anchor = locator->getAnchor ();
2863
- DE.diagnose (anchor->getLoc (),
2864
- diag::conflicting_arguments_for_generic_parameter,
2865
- typeVar->getImpl ().getGenericParameter (), OS.str ());
2880
+ DE.diagnose (loc, diag::conflicting_arguments_for_generic_parameter, GP,
2881
+ OS.str ());
2866
2882
diagnosed = true ;
2867
2883
}
2868
2884
0 commit comments