Skip to content

Commit a278bd2

Browse files
committed
Sema: Infer 'dynamic' even for 'final' @NSManaged properties
Fixes <rdar://problem/35860361>, <https://bugs.swift.org/browse/SR-6534>.
1 parent 45c6315 commit a278bd2

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,6 +2565,10 @@ static void inferDynamic(ASTContext &ctx, ValueDecl *D) {
25652565
if (!DeclAttribute::canAttributeAppearOnDecl(DAK_Dynamic, D))
25662566
return;
25672567

2568+
// The presence of 'dynamic' blocks the inference of 'dynamic'.
2569+
if (D->isDynamic())
2570+
return;
2571+
25682572
// Only 'objc' declarations use 'dynamic'.
25692573
if (!D->isObjC() || D->hasClangNode())
25702574
return;
@@ -2573,16 +2577,16 @@ static void inferDynamic(ASTContext &ctx, ValueDecl *D) {
25732577
(D->getOverriddenDecl() &&
25742578
D->getOverriddenDecl()->hasClangNode());
25752579

2576-
// Only introduce 'dynamic' on declarations...
25772580
bool isNSManaged = D->getAttrs().hasAttribute<NSManagedAttr>();
2578-
if (!isa<ExtensionDecl>(D->getDeclContext())) {
2579-
// ...and in classes on decls marked @NSManaged.
2580-
if (!isNSManaged && !overridesImportedMethod)
2581-
return;
2582-
}
25832581

2584-
// The presence of 'dynamic' or 'final' blocks the inference of 'dynamic'.
2585-
if (D->isDynamic() || D->isFinal())
2582+
bool isExtension = isa<ExtensionDecl>(D->getDeclContext());
2583+
2584+
// We only infer 'dynamic' in these three cases.
2585+
if (!isExtension && !isNSManaged && !overridesImportedMethod)
2586+
return;
2587+
2588+
// The presence of 'final' blocks the inference of 'dynamic'.
2589+
if (D->isFinal() && !isNSManaged)
25862590
return;
25872591

25882592
// Variables declared with 'let' cannot be 'dynamic'.

test/SILGen/objc_attr_NSManaged.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ extension ProtoAdopter {
9595
}
9696

9797

98+
// SR-6534: @NSManaged properties can be 'final'
99+
protocol EntityIDProto {
100+
var entityID: String { get set }
101+
}
102+
103+
class FinalEntity: NSObject, EntityIDProto {
104+
@NSManaged final var entityID: String
105+
}
106+
107+
// CHECK-LABEL: sil private @_T019objc_attr_NSManaged11FinalEntityC8entityIDSSvmytfU_ : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout FinalEntity, @thick FinalEntity.Type) -> ()
108+
// CHECK: objc_method {{.*}} : $FinalEntity, #FinalEntity.entityID!setter.1.foreign
109+
// CHECK: return
110+
111+
// CHECK-LABEL: sil hidden @_T019objc_attr_NSManaged11FinalEntityC8entityIDSSvm : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @guaranteed FinalEntity) -> (Builtin.RawPointer, Optional<Builtin.RawPointer>)
112+
// CHECK: objc_method {{.*}} : $FinalEntity, #FinalEntity.entityID!getter.1.foreign
113+
// CHECK: return
114+
98115
// CHECK-NOT: sil hidden @_T019objc_attr_NSManaged10SwiftGizmoC1xAA1XCfgTo : $@convention(objc_method) (SwiftGizmo) -> @autoreleased X
99116
// CHECK-NOT: sil hidden @_T019objc_attr_NSManaged10SwiftGizmoC1xAA1XCfsTo
100117
// CHECK-NOT: sil hidden @_T019objc_attr_NSManaged10{{[_0-9a-zA-Z]*}}FinalGizmoC1yytfgTo

0 commit comments

Comments
 (0)