@@ -806,11 +806,13 @@ namespace {
806
806
struct FailedArgumentInfo {
807
807
int argumentNumber = -1 ; // /< Arg # at the call site.
808
808
Type parameterType = Type(); // /< Expected type at the decl site.
809
+ DeclContext *declContext = nullptr ; // /< Context at the candidate declaration.
809
810
810
811
bool isValid () const { return argumentNumber != -1 ; }
811
812
812
813
bool operator !=(const FailedArgumentInfo &other) {
813
814
if (argumentNumber != other.argumentNumber ) return true ;
815
+ if (declContext != other.declContext ) return true ;
814
816
// parameterType can be null, and isEqual doesn't handle this.
815
817
if (!parameterType || !other.parameterType )
816
818
return parameterType.getPointer () != other.parameterType .getPointer ();
@@ -1186,6 +1188,8 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
1186
1188
1187
1189
failureInfo.argumentNumber = argNo;
1188
1190
failureInfo.parameterType = paramType;
1191
+ if (paramType->hasTypeParameter ())
1192
+ failureInfo.declContext = dc;
1189
1193
}
1190
1194
}
1191
1195
@@ -1761,18 +1765,25 @@ bool CalleeCandidateInfo::diagnoseAnyStructuralArgumentError(Expr *fnExpr,
1761
1765
// / archetype that has argument type errors, diagnose that error and
1762
1766
// / return true.
1763
1767
bool CalleeCandidateInfo::diagnoseGenericParameterErrors (Expr *badArgExpr) {
1764
- bool foundFailure = false ;
1765
- Type paramType = failedArgument.parameterType ;
1766
1768
Type argType = badArgExpr->getType ();
1767
-
1768
- if (auto genericParam = paramType->getAs <GenericTypeParamType>())
1769
- paramType = genericParam->getDecl ()->getArchetype ();
1770
1769
1771
- if (paramType->is <ArchetypeType>() && !argType->hasTypeVariable () &&
1772
- // FIXME: For protocol argument types, could add specific error
1773
- // similar to could_not_use_member_on_existential.
1774
- !argType->is <ProtocolType>() && !argType->is <ProtocolCompositionType>()) {
1775
- auto archetype = paramType->castTo <ArchetypeType>();
1770
+ // FIXME: For protocol argument types, could add specific error
1771
+ // similar to could_not_use_member_on_existential.
1772
+ if (argType->hasTypeVariable () || argType->is <ProtocolType>() ||
1773
+ argType->is <ProtocolCompositionType>())
1774
+ return false ;
1775
+
1776
+ bool foundFailure = false ;
1777
+ SmallVector<ArchetypeType *, 4 > archetypes;
1778
+ SmallVector<Type, 4 > substitutions;
1779
+
1780
+ if (!findGenericSubstitutions (failedArgument.declContext , failedArgument.parameterType ,
1781
+ argType, archetypes, substitutions))
1782
+ return false ;
1783
+
1784
+ for (unsigned i = 0 , c = archetypes.size (); i < c; i++) {
1785
+ auto archetype = archetypes[i];
1786
+ auto argType = substitutions[i];
1776
1787
1777
1788
// FIXME: Add specific error for not subclass, if the archetype has a superclass?
1778
1789
0 commit comments