Skip to content

Commit a5956a2

Browse files
authored
Merge pull request #15490 from rudkx/rdar38719575
Take the IUO-ness of a parameter declaration into account in ranking.
2 parents efca1ca + 0959f0c commit a5956a2

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,21 @@ static Type getAdjustedParamType(const AnyFunctionType::Param &param) {
384384
return param.getType();
385385
}
386386

387+
// Is a particular parameter of a function or subscript declaration
388+
// declared to be an IUO?
389+
static bool paramIsIUO(Decl *decl, int paramNum) {
390+
if (auto *fn = dyn_cast<AbstractFunctionDecl>(decl)) {
391+
auto *paramList =
392+
fn->getParameterList(fn->getDeclContext()->isTypeContext());
393+
auto *param = paramList->get(paramNum);
394+
return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
395+
}
396+
397+
auto *subscript = cast<SubscriptDecl>(decl);
398+
auto *index = subscript->getIndices()->get(paramNum);
399+
return index->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
400+
}
401+
387402
/// \brief Determine whether the first declaration is as "specialized" as
388403
/// the second declaration.
389404
///
@@ -676,6 +691,17 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
676691
continue;
677692
}
678693

694+
// Emulate behavior from when IUO was a type, where IUOs
695+
// were considered subtypes of plain optionals, but not
696+
// vice-versa. This wouldn't normally happen, but there are
697+
// cases where we can rename imported APIs so that we have a
698+
// name collision, and where the parameter type(s) are the
699+
// same except for details of the kind of optional declared.
700+
auto param1IsIUO = paramIsIUO(decl1, param1);
701+
auto param2IsIUO = paramIsIUO(decl2, param2);
702+
if (param2IsIUO && !param1IsIUO)
703+
return false;
704+
679705
if (!maybeAddSubtypeConstraint(params1[param1], params2[param2]))
680706
return false;
681707

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@import Foundation;
2+
3+
@interface NSObject (NSMyTest)
4+
- (BOOL)isEqualTo:(nullable id)object;
5+
@end
6+
7+
@interface Obj : NSObject
8+
- (BOOL)isEqualToObject:(id)value;
9+
@end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %build-clang-importer-objc-overlays
3+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -import-objc-header %S/Inputs/disambiguate_iuo_param.h %s -emit-ir | %FileCheck %s
4+
// -module-name objc_ir -I %S/Inputs/custom-modules -emit-ir -g -o - -primary-file %s | %FileCheck %s
5+
6+
// REQUIRES: objc_interop
7+
8+
// CHECK: define {{.*}} @main
9+
// CHECK: load {{.*}}, {{.*}}@"\01L_selector(isEqualToObject:)"
10+
let c = Obj()
11+
_ = c.isEqual(to: c)

0 commit comments

Comments
 (0)