Skip to content

Commit f09cb78

Browse files
committed
AST: Property requirements in @objc protocols should return true for requiresForeignGetterAndSetter.
We need to use ObjC dispatch to get to the witness of an ObjC protocol requirement. The wrong answer here was causing us to do the wrong thing when producing identifiers for key paths that refer to ObjC protocol requirements.
1 parent f2de002 commit f09cb78

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

lib/AST/Decl.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4182,8 +4182,8 @@ bool VarDecl::isSelfParameter() const {
41824182
return false;
41834183
}
41844184

4185-
/// Return true if this stored property needs to be accessed with getters and
4186-
/// setters for Objective-C.
4185+
/// Return true if this stored property has a getter and
4186+
/// setter that are accessible from Objective-C.
41874187
bool AbstractStorageDecl::hasForeignGetterAndSetter() const {
41884188
if (auto override = getOverriddenDecl())
41894189
return override->hasForeignGetterAndSetter();
@@ -4204,9 +4204,11 @@ bool AbstractStorageDecl::requiresForeignGetterAndSetter() const {
42044204
// Imported accessors are foreign and only have objc entry points.
42054205
if (hasClangNode())
42064206
return true;
4207-
// Otherwise, we only dispatch by @objc if the declaration is dynamic or
4208-
// NSManaged.
4209-
return isDynamic() || getAttrs().hasAttribute<NSManagedAttr>();
4207+
// Otherwise, we only dispatch by @objc if the declaration is dynamic,
4208+
// NSManaged, or dispatched through an ObjC protocol.
4209+
return isDynamic()
4210+
|| getAttrs().hasAttribute<NSManagedAttr>()
4211+
|| (isa<ProtocolDecl>(getDeclContext()) && isProtocolRequirement());
42104212
}
42114213

42124214

test/SILGen/keypaths_objc.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,15 @@ func nonobjcExtensionOfObjCClass() {
7676
_ = \NSObject.dynamic
7777

7878
}
79+
80+
@objc protocol ObjCProto {
81+
var objcRequirement: Int { get set }
82+
}
83+
84+
// CHECK-LABEL: sil hidden @{{.*}}ProtocolRequirement
85+
func objcProtocolRequirement<T: ObjCProto>(_: T) {
86+
// CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign
87+
_ = \T.objcRequirement
88+
// CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign
89+
_ = \ObjCProto.objcRequirement
90+
}

0 commit comments

Comments
 (0)