Skip to content

Commit d33002c

Browse files
committed
Soften objcImpl selector conflict errors
The recent change to make objcImpl examine class extensions has collided with a workaround some projects were employing where they declared class extension member implementations `private`. Now that we’re checking class extensions in objcImpl extensions, this workaround is creating selector conflict errors in some circumstances. Soften selector conflict errors in objcImpl extensions to warnings so the affected projects continue to build. Fixes rdar://123347290.
1 parent 557628c commit d33002c

5 files changed

+80
-0
lines changed

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2551,6 +2551,12 @@ bool swift::diagnoseObjCMethodConflicts(SourceFile &sf) {
25512551
conflict.selector);
25522552
diag.warnUntilSwiftVersionIf(breakingInSwift5, 6);
25532553

2554+
// Temporarily soften selector conflicts in objcImpl extensions; we're
2555+
// seeing some that are caused by ObjCImplementationChecker improvements.
2556+
if (conflictingDecl->getDeclContext()->getImplementedObjCContext()
2557+
!= conflictingDecl->getDeclContext())
2558+
diag.wrapIn(diag::wrap_objc_implementation_will_become_error);
2559+
25542560
auto objcAttr = getObjCAttrIfFromAccessNote(conflictingDecl);
25552561
swift::softenIfAccessNote(conflictingDecl, objcAttr, diag);
25562562
if (objcAttr)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@import Foundation;
2+
3+
@interface ObjCClass : NSObject
4+
5+
- (void)methodFromHeader1:(int)param;
6+
- (void)methodFromHeader2:(int)param;
7+
8+
@property (readwrite) int propertyFromHeader1;
9+
@property (readwrite) int propertyFromHeader2;
10+
11+
@end
12+
13+
@interface ObjCClass ()
14+
15+
- (void)extensionMethodFromHeader1:(int)param;
16+
- (void)extensionMethodFromHeader2:(int)param;
17+
18+
@property (readwrite) int extensionPropertyFromHeader1;
19+
@property (readwrite) int extensionPropertyFromHeader2;
20+
21+
@end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module objc_implementation_class_extension {
2+
header "objc_implementation_class_extension.h"
3+
export *
4+
}
5+
6+
module objc_implementation_class_extension_internal {
7+
header "objc_implementation_class_extension_internal.h"
8+
export *
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#import "objc_implementation_class_extension.h"
2+
3+
@interface ObjCClass ()
4+
5+
- (void)otherModuleExtensionMethodFromHeader1:(int)param;
6+
- (void)otherModuleExtensionMethodFromHeader2:(int)param;
7+
8+
@property (readwrite) int otherModuleExtensionPropertyFromHeader1;
9+
@property (readwrite) int otherModuleExtensionPropertyFromHeader2;
10+
11+
@end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -import-underlying-module -Xcc -fmodule-map-file=%S/Inputs/objc_implementation_class_extension.modulemap
2+
// REQUIRES: objc_interop
3+
4+
@_implementationOnly import objc_implementation_class_extension_internal
5+
6+
@_objcImplementation extension ObjCClass {
7+
// expected-warning@-1 {{extension for main class interface should provide implementation for instance method 'method(fromHeader2:)'}}
8+
// expected-warning@-2 {{extension for main class interface should provide implementation for property 'propertyFromHeader2'}}
9+
// expected-warning@-3 {{extension for main class interface should provide implementation for instance method 'otherModuleExtensionMethod(fromHeader2:)'}}
10+
// expected-warning@-4 {{extension for main class interface should provide implementation for property 'otherModuleExtensionPropertyFromHeader2'}}
11+
// expected-warning@-5 {{extension for main class interface should provide implementation for instance method 'extensionMethod(fromHeader2:)'}}
12+
// expected-warning@-6 {{extension for main class interface should provide implementation for property 'extensionPropertyFromHeader2'}}
13+
14+
@objc func method(fromHeader1: CInt) {}
15+
@objc private func method(fromHeader2: CInt) {}
16+
17+
@objc var propertyFromHeader1: CInt = 1
18+
@objc private var propertyFromHeader2: CInt = 2
19+
20+
@objc func extensionMethod(fromHeader1: CInt) {}
21+
@objc private func extensionMethod(fromHeader2: CInt) {}
22+
23+
@objc var extensionPropertyFromHeader1: CInt = 1
24+
@objc private var extensionPropertyFromHeader2: CInt = 2
25+
26+
@objc func otherModuleExtensionMethod(fromHeader1: CInt) {}
27+
@objc private func otherModuleExtensionMethod(fromHeader2: CInt) {}
28+
29+
@objc var otherModuleExtensionPropertyFromHeader1: CInt = 1
30+
@objc private var otherModuleExtensionPropertyFromHeader2: CInt = 2
31+
// expected-warning@-1 {{getter for 'otherModuleExtensionPropertyFromHeader2' with Objective-C selector 'otherModuleExtensionPropertyFromHeader2' conflicts with previous declaration with the same Objective-C selector}}
32+
// expected-warning@-2 {{setter for 'otherModuleExtensionPropertyFromHeader2' with Objective-C selector 'setOtherModuleExtensionPropertyFromHeader2:' conflicts with previous declaration with the same Objective-C selector}}
33+
}

0 commit comments

Comments
 (0)