@@ -5937,6 +5937,60 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
5937
5937
}
5938
5938
}
5939
5939
5940
+ static bool parameterTypesMatch (const ValueDecl *derivedDecl,
5941
+ const ValueDecl *baseDecl,
5942
+ TypeMatchOptions matchMode) {
5943
+ const ParameterList *derivedParams;
5944
+ const ParameterList *baseParams;
5945
+ if (auto *derived = dyn_cast<AbstractFunctionDecl>(derivedDecl)) {
5946
+ auto *base = dyn_cast<AbstractFunctionDecl>(baseDecl);
5947
+ if (!base)
5948
+ return false ;
5949
+ baseParams = base->getParameterList (1 );
5950
+ derivedParams = derived->getParameterList (1 );
5951
+ } else {
5952
+ auto *base = dyn_cast<SubscriptDecl>(baseDecl);
5953
+ if (!base)
5954
+ return false ;
5955
+ baseParams = base->getIndices ();
5956
+ derivedParams = cast<SubscriptDecl>(derivedDecl)->getIndices ();
5957
+ }
5958
+
5959
+ if (baseParams->size () != derivedParams->size ())
5960
+ return false ;
5961
+
5962
+ auto subs = SubstitutionMap::getOverrideSubstitutions (baseDecl, derivedDecl,
5963
+ /* derivedSubs=*/ None);
5964
+
5965
+ for (auto i : indices (baseParams->getArray ())) {
5966
+ auto baseItfTy = baseParams->get (i)->getInterfaceType ();
5967
+ auto baseParamTy =
5968
+ baseDecl->getAsGenericContext ()->mapTypeIntoContext (baseItfTy);
5969
+ baseParamTy = baseParamTy.subst (subs);
5970
+ auto derivedParamTy = derivedParams->get (i)->getInterfaceType ();
5971
+
5972
+ // Attempt contravariant match.
5973
+ if (baseParamTy->matchesParameter (derivedParamTy, matchMode))
5974
+ continue ;
5975
+
5976
+ // Try once more for a match, using the underlying type of an
5977
+ // IUO if we're allowing that.
5978
+ if (baseParams->get (i)
5979
+ ->getAttrs ()
5980
+ .hasAttribute <ImplicitlyUnwrappedOptionalAttr>() &&
5981
+ matchMode.contains (TypeMatchFlags::AllowNonOptionalForIUOParam)) {
5982
+ baseParamTy = baseParamTy->getAnyOptionalObjectType ();
5983
+ if (baseParamTy->matches (derivedParamTy, matchMode))
5984
+ continue ;
5985
+ }
5986
+
5987
+ // If there is no match, then we're done.
5988
+ return false ;
5989
+ }
5990
+
5991
+ return true ;
5992
+ }
5993
+
5940
5994
// / Determine which method or subscript this method or subscript overrides
5941
5995
// / (if any).
5942
5996
// /
@@ -6155,8 +6209,22 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
6155
6209
TypeMatchFlags::IgnoreNonEscapingForOptionalFunctionParam;
6156
6210
}
6157
6211
6158
- if (declTy->matches (parentDeclTy, matchMode)) {
6159
- // If the Objective-C selectors match, always call it exact.
6212
+ auto declFnTy = declTy->getAs <AnyFunctionType>();
6213
+ auto parentDeclFnTy = parentDeclTy->getAs <AnyFunctionType>();
6214
+ if (declFnTy && parentDeclFnTy) {
6215
+ auto paramsAndResultMatch = [=]() -> bool {
6216
+ return parameterTypesMatch (decl, parentDecl, matchMode) &&
6217
+ declFnTy->getResult ()->matches (parentDeclFnTy->getResult (),
6218
+ matchMode);
6219
+ };
6220
+
6221
+ if (declFnTy->matchesFunctionType (parentDeclFnTy, matchMode,
6222
+ paramsAndResultMatch)) {
6223
+ matches.push_back ({parentDecl, objCMatch, parentDeclTy});
6224
+ hadExactMatch |= objCMatch;
6225
+ continue ;
6226
+ }
6227
+ } else if (declTy->matches (parentDeclTy, matchMode)) {
6160
6228
matches.push_back ({parentDecl, objCMatch, parentDeclTy});
6161
6229
hadExactMatch |= objCMatch;
6162
6230
continue ;
0 commit comments