@@ -1860,6 +1860,7 @@ suggestPotentialOverloads(SourceLoc loc, bool isResult) {
1860
1860
// / archetype that has argument type errors, diagnose that error and
1861
1861
// / return true.
1862
1862
bool CalleeCandidateInfo::diagnoseGenericParameterErrors (Expr *badArgExpr) {
1863
+ TypeChecker &TC = CS.TC ;
1863
1864
Type argType = CS.getType (badArgExpr);
1864
1865
1865
1866
// FIXME: For protocol argument types, could add specific error
@@ -1876,23 +1877,70 @@ bool CalleeCandidateInfo::diagnoseGenericParameterErrors(Expr *badArgExpr) {
1876
1877
argType, archetypesMap))
1877
1878
return false ;
1878
1879
1880
+ auto getGenericTypeDecl = [&](ArchetypeType *archetype) -> ValueDecl * {
1881
+ auto *env = archetype->getGenericEnvironment ();
1882
+ auto paramType = env->mapTypeOutOfContext (archetype);
1883
+
1884
+ if (auto *GTPT = paramType->getAs <GenericTypeParamType>())
1885
+ return GTPT->getDecl ();
1886
+
1887
+ if (auto *DMT = paramType->getAs <DependentMemberType>())
1888
+ return DMT->getAssocType ();
1889
+
1890
+ return nullptr ;
1891
+ };
1892
+
1893
+ auto describeGenericType = [&](ValueDecl *genericParam,
1894
+ bool includeName = false ) -> std::string {
1895
+ if (!genericParam)
1896
+ return " " ;
1897
+
1898
+ Decl *parent = nullptr ;
1899
+ if (auto *AT = dyn_cast<AssociatedTypeDecl>(genericParam)) {
1900
+ parent = AT->getProtocol ();
1901
+ } else {
1902
+ auto *dc = genericParam->getDeclContext ();
1903
+ parent = dc->getInnermostDeclarationDeclContext ();
1904
+ }
1905
+
1906
+ if (!parent)
1907
+ return " " ;
1908
+
1909
+ llvm::SmallString<64 > result;
1910
+ llvm::raw_svector_ostream OS (result);
1911
+
1912
+ OS << Decl::getDescriptiveKindName (genericParam->getDescriptiveKind ());
1913
+
1914
+ if (includeName && genericParam->hasName ())
1915
+ OS << " '" << genericParam->getBaseName () << " '" ;
1916
+
1917
+ OS << " of " ;
1918
+ OS << Decl::getDescriptiveKindName (parent->getDescriptiveKind ());
1919
+ if (auto *decl = dyn_cast<ValueDecl>(parent)) {
1920
+ if (decl->hasName ())
1921
+ OS << " '" << decl->getFullName () << " '" ;
1922
+ }
1923
+
1924
+ return OS.str ();
1925
+ };
1926
+
1879
1927
for (auto pair : archetypesMap) {
1880
- auto archetype = pair.first ->castTo <ArchetypeType>();
1928
+ auto paramArchetype = pair.first ->castTo <ArchetypeType>();
1881
1929
auto substitution = pair.second ;
1882
1930
1883
1931
// FIXME: Add specific error for not subclass, if the archetype has a superclass?
1884
1932
1885
1933
// Check for optional near miss.
1886
1934
if (auto argOptType = substitution->getOptionalObjectType ()) {
1887
- if (CS.TC .isSubstitutableFor (argOptType, archetype , CS.DC )) {
1935
+ if (CS.TC .isSubstitutableFor (argOptType, paramArchetype , CS.DC )) {
1888
1936
CS.TC .diagnose (badArgExpr->getLoc (), diag::missing_unwrap_optional,
1889
1937
argType);
1890
1938
foundFailure = true ;
1891
- continue ;
1939
+ break ;
1892
1940
}
1893
1941
}
1894
-
1895
- for (auto proto : archetype ->getConformsTo ()) {
1942
+
1943
+ for (auto proto : paramArchetype ->getConformsTo ()) {
1896
1944
if (!CS.TC .conformsToProtocol (substitution, proto, CS.DC ,
1897
1945
ConformanceCheckFlags::InExpression)) {
1898
1946
if (substitution->isEqual (argType)) {
@@ -1905,9 +1953,38 @@ bool CalleeCandidateInfo::diagnoseGenericParameterErrors(Expr *badArgExpr) {
1905
1953
argType, substitution, proto->getDeclaredType ());
1906
1954
}
1907
1955
foundFailure = true ;
1956
+ break ;
1908
1957
}
1909
1958
}
1959
+
1960
+ if (auto *argArchetype = substitution->getAs <ArchetypeType>()) {
1961
+ // Produce this diagnostic only if the names
1962
+ // of the generic parameters are the same.
1963
+ if (argArchetype->getName () != paramArchetype->getName ())
1964
+ continue ;
1965
+
1966
+ auto *paramDecl = getGenericTypeDecl (paramArchetype);
1967
+ auto *argDecl = getGenericTypeDecl (argArchetype);
1968
+
1969
+ if (!paramDecl || !argDecl)
1970
+ continue ;
1971
+
1972
+ TC.diagnose (badArgExpr->getLoc (),
1973
+ diag::cannot_convert_argument_value_generic, argArchetype,
1974
+ describeGenericType (argDecl), paramArchetype,
1975
+ describeGenericType (paramDecl));
1976
+
1977
+ TC.diagnose (paramDecl, diag::descriptive_generic_type_declared_here,
1978
+ describeGenericType (paramDecl, true ));
1979
+
1980
+ TC.diagnose (argDecl, diag::descriptive_generic_type_declared_here,
1981
+ describeGenericType (argDecl, true ));
1982
+
1983
+ foundFailure = true ;
1984
+ break ;
1985
+ }
1910
1986
}
1987
+
1911
1988
return foundFailure;
1912
1989
}
1913
1990
0 commit comments