Skip to content

[ModuleInterfaces] Don't diagnose @NSManaged properties with accessors #27676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/Sema/TypeCheckStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2538,7 +2538,16 @@ static void finishNSManagedImplInfo(VarDecl *var,
if (var->isLet())
diagnoseAndRemoveAttr(var, attr, diag::attr_NSManaged_let_property);

SourceFile *parentFile = var->getDeclContext()->getParentSourceFile();

auto diagnoseNotStored = [&](unsigned kind) {
// Skip diagnosing @NSManaged declarations in module interfaces. They are
// properties that are stored, but have specially synthesized observers
// and we should allow them to have getters and setters in a module
// interface.
if (parentFile && parentFile->Kind == SourceFileKind::Interface)
return;

diagnoseAndRemoveAttr(var, attr, diag::attr_NSManaged_not_stored, kind);
};

Expand Down
41 changes: 41 additions & 0 deletions test/ModuleInterface/nsmanaged-attr.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// RUN: %empty-directory(%t)

// This test ensures we can properly load modules that have @NSManaged properties.

// 1. Emit this file to a module interface
// RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/Module.swiftinterface %s -enable-library-evolution -module-name Module

// 2. Check the interface against what we expect
// RUN: %FileCheck %s < %t/Module.swiftinterface

// 3. Ensure we can load this module from its interface
// RUN: echo 'import Module' | %target-swift-frontend -typecheck - -I %t

// REQUIRES: objc_interop

import CoreData
import Foundation

// CHECK: @objc public class MyObject : CoreData.NSManagedObject {
public class MyObject: NSManagedObject {
// CHECK: @objc @NSManaged dynamic public var myVar: Swift.String {
// CHECK-NEXT: @objc get
// CHECK-NEXT: @objc set
// CHECK-NEXT: }
@NSManaged public var myVar: String
// CHECK: @NSManaged @objc dynamic public var myVar2: Swift.String {
// CHECK-NEXT: @objc get
// CHECK-NEXT: @objc set
// CHECK-NEXT: }
@NSManaged @objc public var myVar2: String
// CHECK: @NSManaged @objc dynamic public var myVar3: Swift.String {
// CHECK-NEXT: @objc get
// CHECK-NEXT: @objc set
// CHECK-NEXT: }
@NSManaged @objc dynamic public var myVar3: String
// CHECK: @NSManaged @objc dynamic public var myVar4: Swift.String {
// CHECK-NEXT: @objc get
// CHECK-NEXT: }
@NSManaged @objc dynamic public private(set) var myVar4: String
// CHECK: }
}