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