Skip to content

Commit 5a7456f

Browse files
nkcsgexibeccadax
authored andcommitted
Merge pull request #74801 from beccadax/objcimpl-enablement
Enable @objc @implementation (SE-0436) as an ordinary language feature
1 parent 302ad00 commit 5a7456f

8 files changed

+32
-37
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,16 +1764,16 @@ ERROR(attr_objc_implementation_must_be_unconditional,none,
17641764
"only unconditional extensions can implement an Objective-C '@interface'",
17651765
())
17661766
ERROR(attr_objc_implementation_must_be_imported,none,
1767-
"'@_objcImplementation' cannot be used to extend %kind0 because it was "
1767+
"'@objc @implementation' cannot be used to extend %kind0 because it was "
17681768
"defined by a Swift 'class' declaration, not an imported Objective-C "
17691769
"'@interface' declaration",
17701770
(ValueDecl *))
17711771
ERROR(attr_objc_implementation_must_have_super,none,
1772-
"'@_objcImplementation' cannot be used to implement root %kind0; declare "
1773-
"its superclass in the header",
1772+
"'@objc @implementation' cannot be used to implement root %kind0; "
1773+
"declare its superclass in the header",
17741774
(ValueDecl *))
17751775
ERROR(objc_implementation_cannot_have_generics,none,
1776-
"'@_objcImplementation' cannot be used to implement %kind0",
1776+
"'@objc @implementation' cannot be used to implement %kind0",
17771777
(ValueDecl *))
17781778
ERROR(attr_objc_implementation_category_not_found,none,
17791779
"could not find category %0 on Objective-C class %1; make sure your "
@@ -1791,7 +1791,7 @@ ERROR(attr_objc_implementation_no_category_for_func,none,
17911791
"name from this attribute",
17921792
(ValueDecl*))
17931793
ERROR(attr_objc_implementation_no_conformance,none,
1794-
"'@_objcImplementation' extension cannot add conformance to %0; "
1794+
"'@objc @implementation' extension cannot add conformance to %0; "
17951795
"add this conformance %select{with an ordinary extension|"
17961796
"in the Objective-C header}1",
17971797
(Type, bool))
@@ -1919,7 +1919,7 @@ NOTE(objc_implementation_requirement_here,none,
19191919
(ValueDecl *))
19201920

19211921
ERROR(objc_implementation_init_must_be_convenience, none,
1922-
"%kind0 is not valid in an '@_objcImplementation' extension because "
1922+
"%kind0 is not valid in an '@objc @implementation' extension because "
19231923
"Objective-C subclasses must be able to override "
19241924
"%select{designated|required}1 initializers",
19251925
(const ValueDecl *, /*isRequired=*/bool))
@@ -1933,7 +1933,7 @@ NOTE(objc_implementation_init_turn_required_to_convenience, none,
19331933

19341934
// Fallback diagnostic; super-general by nature.
19351935
ERROR(objc_implementation_member_requires_vtable, none,
1936-
"%kind0 is not valid in an '@_objcImplementation' extension because it "
1936+
"%kind0 is not valid in an '@objc @implementation' extension because it "
19371937
"is an overridable Swift-only %kindonly0",
19381938
(const ValueDecl *))
19391939

include/swift/Basic/Features.def

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(SendingArgsAndResults, 430, "Sending arg and resul
201201
LANGUAGE_FEATURE(BorrowingSwitch, 432, "Noncopyable type pattern matching")
202202
CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(IsolatedAny, 431, "@isolated(any) function types")
203203
LANGUAGE_FEATURE(IsolatedAny2, 431, "@isolated(any) function types")
204+
LANGUAGE_FEATURE(ObjCImplementation, 436, "@objc @implementation extensions")
204205

205206
// Swift 6
206207
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -375,9 +376,6 @@ EXPERIMENTAL_FEATURE(ClosureIsolation, true)
375376
// Whether lookup of members respects the enclosing file's imports.
376377
EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE(MemberImportVisibility, true)
377378

378-
// Enable @implementation on extensions of ObjC classes.
379-
EXPERIMENTAL_FEATURE(ObjCImplementation, true)
380-
381379
// Enable @implementation on extensions of ObjC classes with non-fixed layout
382380
// due to resilient stored properties. Requires OS support; this flag exists for
383381
// staging purposes.

test/IRGen/objc_implementation_deployment_target_resilience.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -target %target-stable-abi-triple -I %S/Inputs/abi -F %clang-importer-sdk-path/frameworks %s -import-objc-header %S/Inputs/objc_implementation.h -emit-ir -o %t.ir -enable-library-evolution -enable-experimental-feature ObjCImplementationWithResilientStorage -target %target-future-triple
33
// REQUIRES: objc_interop
44

5-
@_objcImplementation extension ImplClassWithResilientStoredProperty {
5+
@objc @implementation extension ImplClassWithResilientStoredProperty {
66
@objc var beforeInt: Int32 = 0 // no-error
77
final var a: Mirror? // expected-error {{does not support stored properties whose size can change due to library evolution; store this value in an object or 'any' type}}
88
final var b: AnyKeyPath? // no-error

test/decl/ext/objc_implementation.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ protocol EmptySwiftProto {}
1010
// FIXME: give better diagnostic expected-error@-4 {{extension for main class interface should provide implementation for property 'propertyFromHeader8'}}
1111
// FIXME: give better diagnostic expected-error@-5 {{extension for main class interface should provide implementation for property 'propertyFromHeader7'}}
1212
// FIXME: give better diagnostic expected-error@-6 {{extension for main class interface should provide implementation for instance method 'method(fromHeader3:)'}}
13-
// expected-error@-7 {{'@_objcImplementation' extension cannot add conformance to 'EmptySwiftProto'; add this conformance with an ordinary extension}}
14-
// expected-error@-8 {{'@_objcImplementation' extension cannot add conformance to 'EmptyObjCProto'; add this conformance in the Objective-C header}}
13+
// expected-error@-7 {{'@objc @implementation' extension cannot add conformance to 'EmptySwiftProto'; add this conformance with an ordinary extension}}
14+
// expected-error@-8 {{'@objc @implementation' extension cannot add conformance to 'EmptyObjCProto'; add this conformance in the Objective-C header}}
1515
// expected-error@-9 {{extension for main class interface should provide implementation for instance method 'extensionMethod(fromHeader2:)'}}
1616

1717
func method(fromHeader1: CInt) {
@@ -204,12 +204,12 @@ protocol EmptySwiftProto {}
204204
}
205205

206206
@nonobjc public init(notFromHeader4: CInt) {
207-
// expected-error@-1 {{initializer 'init(notFromHeader4:)' is not valid in an '@_objcImplementation' extension because Objective-C subclasses must be able to override designated initializers}}
207+
// expected-error@-1 {{initializer 'init(notFromHeader4:)' is not valid in an '@objc @implementation' extension because Objective-C subclasses must be able to override designated initializers}}
208208
// expected-note@-2 {{add 'convenience' keyword to make this a convenience initializer}} {{12-12=convenience }}
209209
}
210210

211211
@nonobjc public required init(notFromHeader5: CInt) {
212-
// expected-error@-1 {{initializer 'init(notFromHeader5:)' is not valid in an '@_objcImplementation' extension because Objective-C subclasses must be able to override required initializers}}
212+
// expected-error@-1 {{initializer 'init(notFromHeader5:)' is not valid in an '@objc @implementation' extension because Objective-C subclasses must be able to override required initializers}}
213213
// expected-note@-2 {{replace 'required' keyword with 'convenience' to make this a convenience initializer}} {{19-27=convenience}}
214214
}
215215

@@ -475,17 +475,17 @@ protocol EmptySwiftProto {}
475475
// expected-note@-1 2 {{'SwiftClass' declared here}}
476476

477477
@objc @implementation extension SwiftClass {}
478-
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{7-23=}}
478+
// expected-error@-1 {{'@objc @implementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{7-23=}}
479479

480480
@objc(WTF) @implementation extension SwiftClass {} // expected
481-
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{12-28=}}
481+
// expected-error@-1 {{'@objc @implementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{12-28=}}
482482

483483
@objc @implementation extension ObjCImplRootClass {
484-
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement root class 'ObjCImplRootClass'; declare its superclass in the header}}
484+
// expected-error@-1 {{'@objc @implementation' cannot be used to implement root class 'ObjCImplRootClass'; declare its superclass in the header}}
485485
}
486486

487487
@objc @implementation extension ObjCImplGenericClass {
488-
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement generic class 'ObjCImplGenericClass'}}
488+
// expected-error@-1 {{'@objc @implementation' cannot be used to implement generic class 'ObjCImplGenericClass'}}
489489
}
490490

491491
@implementation extension ObjCBadClass {

test/decl/ext/objc_implementation_conflicts.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import objc_implementation_private
1212
#endif
1313

14-
@_objcImplementation extension ObjCClass {
14+
@objc @implementation extension ObjCClass {
1515
@objc func method(fromHeader1: CInt) {
1616
// OK, provides an implementation for the header's method.
1717
}
@@ -179,7 +179,7 @@ import objc_implementation_private
179179
let rdar122280735: (@escaping () -> ()) -> Void = { _ in }
180180
}
181181

182-
@_objcImplementation(PresentAdditions) extension ObjCClass {
182+
@objc(PresentAdditions) @implementation extension ObjCClass {
183183
@objc func categoryMethod(fromHeader3: CInt) {
184184
// OK
185185
}

test/decl/ext/objc_implementation_early_adopter.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ protocol EmptySwiftProto {}
1010
// FIXME: give better diagnostic expected-warning@-4 {{extension for main class interface should provide implementation for property 'propertyFromHeader8'}}
1111
// FIXME: give better diagnostic expected-warning@-5 {{extension for main class interface should provide implementation for property 'propertyFromHeader7'}}
1212
// FIXME: give better diagnostic expected-warning@-6 {{extension for main class interface should provide implementation for instance method 'method(fromHeader3:)'}}
13-
// expected-warning@-7 {{'@_objcImplementation' extension cannot add conformance to 'EmptySwiftProto'; add this conformance with an ordinary extension}}
14-
// expected-warning@-8 {{'@_objcImplementation' extension cannot add conformance to 'EmptyObjCProto'; add this conformance in the Objective-C header}}
13+
// expected-warning@-7 {{'@objc @implementation' extension cannot add conformance to 'EmptySwiftProto'; add this conformance with an ordinary extension}}
14+
// expected-warning@-8 {{'@objc @implementation' extension cannot add conformance to 'EmptyObjCProto'; add this conformance in the Objective-C header}}
1515
// expected-warning@-9 {{extension for main class interface should provide implementation for instance method 'extensionMethod(fromHeader2:)'}}
1616

1717
func method(fromHeader1: CInt) {
@@ -204,12 +204,12 @@ protocol EmptySwiftProto {}
204204
}
205205

206206
@nonobjc public init(notFromHeader4: CInt) {
207-
// expected-warning@-1 {{initializer 'init(notFromHeader4:)' is not valid in an '@_objcImplementation' extension because Objective-C subclasses must be able to override designated initializers}}
207+
// expected-warning@-1 {{initializer 'init(notFromHeader4:)' is not valid in an '@objc @implementation' extension because Objective-C subclasses must be able to override designated initializers}}
208208
// expected-note@-2 {{add 'convenience' keyword to make this a convenience initializer}} {{12-12=convenience }}
209209
}
210210

211211
@nonobjc public required init(notFromHeader5: CInt) {
212-
// expected-warning@-1 {{initializer 'init(notFromHeader5:)' is not valid in an '@_objcImplementation' extension because Objective-C subclasses must be able to override required initializers}}
212+
// expected-warning@-1 {{initializer 'init(notFromHeader5:)' is not valid in an '@objc @implementation' extension because Objective-C subclasses must be able to override required initializers}}
213213
// expected-note@-2 {{replace 'required' keyword with 'convenience' to make this a convenience initializer}} {{19-27=convenience}}
214214
}
215215

@@ -477,17 +477,17 @@ protocol EmptySwiftProto {}
477477
// expected-note@-1 2 {{'SwiftClass' declared here}}
478478

479479
@_objcImplementation extension SwiftClass {}
480-
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-22=}}
480+
// expected-error@-1 {{'@objc @implementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-22=}}
481481

482482
@_objcImplementation(WTF) extension SwiftClass {} // expected
483-
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-27=}}
483+
// expected-error@-1 {{'@objc @implementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-27=}}
484484

485485
@_objcImplementation extension ObjCImplRootClass {
486-
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement root class 'ObjCImplRootClass'; declare its superclass in the header}}
486+
// expected-error@-1 {{'@objc @implementation' cannot be used to implement root class 'ObjCImplRootClass'; declare its superclass in the header}}
487487
}
488488

489489
@_objcImplementation extension ObjCImplGenericClass {
490-
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement generic class 'ObjCImplGenericClass'}}
490+
// expected-error@-1 {{'@objc @implementation' cannot be used to implement generic class 'ObjCImplGenericClass'}}
491491
}
492492

493493
//
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
// REQUIRES: objc_interop
22

3-
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -typecheck %s -import-objc-header %S/Inputs/objc_implementation.h 2>&1 | %FileCheck --check-prefixes NO,CHECK %s
4-
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -typecheck %s -import-objc-header %S/Inputs/objc_implementation.h -enable-experimental-feature ObjCImplementation 2>&1 | %FileCheck --check-prefixes YES,CHECK %s
3+
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -typecheck %s -import-objc-header %S/Inputs/objc_implementation.h 2>&1 | %FileCheck %s
54

6-
// NO-NOT: objc_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: warning: '@_objcImplementation' is deprecated; use '@implementation' instead
7-
// YES-DAG: objc_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: warning: '@_objcImplementation' is deprecated; use '@implementation' instead
5+
// CHECK-DAG: objc_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: warning: '@_objcImplementation' is deprecated; use '@implementation' instead
86
@_objcImplementation(EmptyCategory) extension ObjCClass {}
97

108
// CHECK-DAG: objc_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: warning: extension for main class interface should provide implementation for instance method 'subclassMethod(fromHeader1:)'; this will become an error after adopting '@implementation'
119
// CHECK-NOT: objc_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: warning: '@_objcImplementation' is deprecated; use '@implementation' instead
1210
@_objcImplementation extension ObjCSubclass {}
1311

14-
// CHECK-DAG: objc_implementation_features.swift:[[@LINE+3]]:{{[0-9]+}}: error: extension for main class interface should provide implementation for initializer 'init()'{{$}}
15-
// NO-DAG: objc_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: error: 'implementation' attribute is only valid when experimental feature ObjCImplementation is enabled
16-
// YES-NOT: objc_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: error: 'implementation' attribute is only valid when experimental feature ObjCImplementation is enabled
12+
// CHECK-DAG: objc_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: error: extension for main class interface should provide implementation for initializer 'init()'{{$}}
13+
// CHECK-NOT: objc_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: error: 'implementation' attribute is only valid when experimental feature ObjCImplementation is enabled
1714
@objc @implementation extension ObjCBasicInitClass {}

test/decl/ext/objc_implementation_impl_only.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
@_implementationOnly import objc_implementation_internal
55

6-
@_objcImplementation extension InternalObjCClass {
6+
@objc @implementation extension InternalObjCClass {
77
@objc public func method(fromHeader1: CInt) {
88
// OK
99
}

0 commit comments

Comments
 (0)