@@ -904,16 +904,44 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
904904 // before pointer types could be compared.
905905 auto locator = getLocator ();
906906 auto path = locator->getPath ();
907- unsigned toDrop = 0 ;
908- for (const auto &elt : llvm::reverse (path)) {
909- if (!elt.is <LocatorPathElt::OptionalPayload>())
910- break ;
911907
912- // Disregard optional payload element to look at its source.
913- ++toDrop;
908+ // If there are generic types involved, we need to find
909+ // the outermost generic types and report on them instead
910+ // of their arguments.
911+ // For example:
912+ //
913+ // <expr> -> contextual type
914+ // -> generic type S<[Int]>
915+ // -> generic type S<[String]>
916+ // -> generic argument #0
917+ //
918+ // Is going to have from/to types as `[Int]` and `[String]` but
919+ // the diagnostic should mention `S<[Int]>` and `S<[String]>`
920+ // because it refers to a contextual type location.
921+ if (locator->isLastElement <LocatorPathElt::GenericArgument>()) {
922+ for (unsigned i = 0 ; i < path.size (); ++i) {
923+ if (auto genericType = path[i].getAs <LocatorPathElt::GenericType>()) {
924+ ASSERT (i + 1 < path.size ());
925+
926+ fromType = resolveType (genericType->getType ());
927+ toType = resolveType (
928+ path[i + 1 ].castTo <LocatorPathElt::GenericType>().getType ());
929+ break ;
930+ }
931+ }
914932 }
915933
916- path = path.drop_back (toDrop);
934+ while (!path.empty ()) {
935+ auto last = path.back ();
936+ if (last.is <LocatorPathElt::OptionalPayload>() ||
937+ last.is <LocatorPathElt::GenericType>() ||
938+ last.is <LocatorPathElt::GenericArgument>()) {
939+ path = path.drop_back ();
940+ continue ;
941+ }
942+
943+ break ;
944+ }
917945
918946 std::optional<Diag<Type, Type>> diagnostic;
919947 if (path.empty ()) {
0 commit comments