@@ -2778,45 +2778,61 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
27782778
27792779 auto &DE = cs.getASTContext ().Diags ;
27802780
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+ }
27822806
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;
27852810
2786- if (!typeVar->getImpl ().getGenericParameter ())
2787- continue ;
2811+ for (const auto &entry : genericParams) {
2812+ auto *typeVar = entry.first ;
2813+ auto GP = entry.second ;
27882814
27892815 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 ();
28102826 }
2827+ return false ;
2828+ });
2829+ }
28112830
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);
28192832 }
2833+
2834+ if (arguments.size () > 1 )
2835+ conflicts[GP].append (arguments.begin (), arguments.end ());
28202836 }
28212837
28222838 auto getGenericTypeDecl = [&](ArchetypeType *archetype) -> ValueDecl * {
@@ -2833,8 +2849,10 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
28332849
28342850 bool diagnosed = false ;
28352851 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 ;
28382856 auto conflictingArguments = conflict.second ;
28392857
28402858 llvm::SmallString<64 > arguments;
@@ -2859,10 +2877,8 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
28592877 },
28602878 [&OS] { OS << " vs. " ; });
28612879
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 ());
28662882 diagnosed = true ;
28672883 }
28682884
0 commit comments