SE-495: Make CImplementation an official feature

This commit is contained in:
Alexis Laferrière
2025-10-24 11:33:44 -07:00
parent 000c2604b0
commit bce585c133
4 changed files with 23 additions and 32 deletions

View File

@@ -278,6 +278,7 @@ LANGUAGE_FEATURE(InoutLifetimeDependence, 0, "Support @_lifetime(&)")
SUPPRESSIBLE_LANGUAGE_FEATURE(NonexhaustiveAttribute, 487, "Nonexhaustive Enums")
LANGUAGE_FEATURE(ModuleSelector, 491, "Module selectors (`Module::name` syntax)")
LANGUAGE_FEATURE(CDecl, 495, "C compatible functions and enums with @c")
LANGUAGE_FEATURE(CImplementation, 495, "C compatible functions and enums with @c")
// Swift 6
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -470,9 +471,6 @@ EXPERIMENTAL_FEATURE(ClosureIsolation, true)
// staging purposes.
EXPERIMENTAL_FEATURE(ObjCImplementationWithResilientStorage, true)
// Enable @implementation on @_cdecl functions.
EXPERIMENTAL_FEATURE(CImplementation, true)
// Enable @sensitive attribute.
EXPERIMENTAL_FEATURE(Sensitive, true)

View File

@@ -4197,11 +4197,6 @@ public:
!decl->getASTContext().LangOpts.hasFeature(Feature::CImplementation))
return;
// Only encourage @_objcImplementation *extension* adopters to adopt
// @implementation; @_objcImplementation @_cdecl hasn't been stabilized yet.
if (!isa<ExtensionDecl>(decl))
return;
auto diag = diagnose(getAttr()->getLocation(),
diag::objc_implementation_early_spelling_deprecated);
diag.fixItReplace(getAttr()->getRangeWithAt(), "@implementation");

View File

@@ -1,15 +1,13 @@
// 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
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -typecheck %s -import-objc-header %S/Inputs/objc_implementation.h -enable-experimental-feature CImplementation 2>&1 | %FileCheck --check-prefixes YES,C,CHECK %s
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -typecheck %s -import-objc-header %S/Inputs/objc_implementation.h > %t 2>&1
// RUN: %FileCheck --input-file %t --check-prefixes YES,CHECK %s
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -typecheck %s -import-objc-header %S/Inputs/objc_implementation.h -enable-experimental-feature CImplementation > %t 2>&1
// RUN: %FileCheck --input-file %t --check-prefixes YES,C,CHECK %s
// REQUIRES: swift_feature_CImplementation
// YES-DAG: cdecl_implementation_features.swift:[[@LINE+4]]:{{[0-9]+}}: warning: global function 'CImplFunc1' of type '(Double) -> ()' does not match type '(Int32) -> Void' declared by the header; this will become an error after adopting '@implementation'
// NO-DAG: cdecl_implementation_features.swift:[[@LINE+3]]:{{[0-9]+}}: error: '_objcImplementation' attribute is only valid when experimental feature CImplementation is enabled
// YES-NOT: cdecl_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: warning: '@_objcImplementation' is deprecated; use '@implementation' instead
// TODO: When @implementation @_cdecl stabilizes, YES-NOT on the line above will become YES-DAG
// YES-DAG: cdecl_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: warning: global function 'CImplFunc1' of type '(Double) -> ()' does not match type '(Int32) -> Void' declared by the header; this will become an error after adopting '@implementation'
@_objcImplementation @_cdecl("CImplFunc1") func CImplFunc1(_: Double) {}
// YES-DAG: cdecl_implementation_features.swift:[[@LINE+3]]:{{[0-9]+}}: error: global function 'CImplFunc2' of type '(Double) -> ()' does not match type '(Int32) -> Void' declared by the header{{$}}
// NO-DAG: cdecl_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: error: 'implementation' attribute is only valid when experimental feature CImplementation is enabled
// YES-DAG: cdecl_implementation_features.swift:[[@LINE+2]]:{{[0-9]+}}: error: global function 'CImplFunc2' of type '(Double) -> ()' does not match type '(Int32) -> Void' declared by the header{{$}}
// YES-NOT: cdecl_implementation_features.swift:[[@LINE+1]]:{{[0-9]+}}: error: 'implementation' attribute is only valid when experimental feature CImplementation is enabled
@implementation @_cdecl("CImplFunc2") func CImplFunc2(_: Double) {}

View File

@@ -537,14 +537,14 @@ protocol EmptySwiftProto {}
// @_cdecl for global functions
//
@_objcImplementation @_cdecl("CImplFunc1")
@implementation @_cdecl("CImplFunc1")
func CImplFunc1(_: Int32) {
// OK
}
@_objcImplementation(BadCategory) @_cdecl("CImplFunc2")
@implementation(BadCategory) @_cdecl("CImplFunc2")
func CImplFunc2(_: Int32) {
// expected-error@-2 {{global function 'CImplFunc2' does not belong to an Objective-C category; remove the category name from this attribute}} {{21-34=}}
// expected-error@-2 {{global function 'CImplFunc2' does not belong to an Objective-C category; remove the category name from this attribute}} {{16-29=}}
}
@_objcImplementation @_cdecl("CImplFuncMissing")
@@ -557,12 +557,12 @@ func CImplFuncMismatch1(_: Float) {
// expected-warning@-1 {{global function 'CImplFuncMismatch1' of type '(Float) -> ()' does not match type '(Int32) -> Void' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch2")
@implementation @_cdecl("CImplFuncMismatch2")
func CImplFuncMismatch2(_: Int32) -> Float {
// expected-warning@-1 {{global function 'CImplFuncMismatch2' of type '(Int32) -> Float' does not match type '(Int32) -> Void' declared by the header}}
// expected-error@-1 {{global function 'CImplFuncMismatch2' of type '(Int32) -> Float' does not match type '(Int32) -> Void' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch3")
@implementation @_cdecl("CImplFuncMismatch3")
func CImplFuncMismatch3(_: Any?) {
// OK
}
@@ -572,18 +572,18 @@ func CImplFuncMismatch4(_: Any) {
// expected-warning@-1 {{global function 'CImplFuncMismatch4' of type '(Any) -> ()' does not match type '(Any?) -> Void' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch5")
@implementation @_cdecl("CImplFuncMismatch5")
func CImplFuncMismatch5(_: Any) {
// OK
}
@_objcImplementation @_cdecl("CImplFuncMismatch6")
@implementation @_cdecl("CImplFuncMismatch6")
func CImplFuncMismatch6(_: Any!) {
// OK, mismatch allowed
}
@_objcImplementation @_cdecl("CImplFuncMismatch3a")
@implementation @_cdecl("CImplFuncMismatch3a")
func CImplFuncMismatch3a(_: Int32) -> Any? {
// OK
}
@@ -593,23 +593,23 @@ func CImplFuncMismatch4a(_: Int32) -> Any {
// expected-warning@-1 {{global function 'CImplFuncMismatch4a' of type '(Int32) -> Any' does not match type '(Int32) -> Any?' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch5a")
@implementation @_cdecl("CImplFuncMismatch5a")
func CImplFuncMismatch5a(_: Int32) -> Any {
// OK
}
@_objcImplementation @_cdecl("CImplFuncMismatch6a")
@implementation @_cdecl("CImplFuncMismatch6a")
func CImplFuncMismatch6a(_: Int32) -> Any! {
// OK, mismatch allowed
}
@_objcImplementation @_cdecl("CImplFuncNameMismatch1")
@implementation @_cdecl("CImplFuncNameMismatch1")
func mismatchedName1(_: Int32) {
// expected-error@-2 {{could not find imported function 'CImplFuncNameMismatch1' matching global function 'mismatchedName1'; make sure you import the module or header that declares it}}
// FIXME: Improve diagnostic for a partial match.
}
@_objcImplementation @_cdecl("mismatchedName2")
@implementation @_cdecl("mismatchedName2")
func CImplFuncNameMismatch2(_: Int32) {
// expected-error@-2 {{could not find imported function 'mismatchedName2' matching global function 'CImplFuncNameMismatch2'; make sure you import the module or header that declares it}}
// FIXME: Improve diagnostic for a partial match.
@@ -619,14 +619,14 @@ func CImplFuncNameMismatch2(_: Int32) {
// TODO: @_cdecl for global functions imported as computed vars
//
var cImplComputedGlobal1: Int32 {
@_objcImplementation @_cdecl("CImplGetComputedGlobal1")
@implementation @_cdecl("CImplGetComputedGlobal1")
get {
// FIXME: Lookup for vars isn't working yet
// expected-error@-3 {{could not find imported function 'CImplGetComputedGlobal1' matching getter for var 'cImplComputedGlobal1'; make sure you import the module or header that declares it}}
return 0
}
@_objcImplementation @_cdecl("CImplSetComputedGlobal1")
@implementation @_cdecl("CImplSetComputedGlobal1")
set {
// FIXME: Lookup for vars isn't working yet
// expected-error@-3 {{could not find imported function 'CImplSetComputedGlobal1' matching setter for var 'cImplComputedGlobal1'; make sure you import the module or header that declares it}}
@@ -638,7 +638,7 @@ var cImplComputedGlobal1: Int32 {
// TODO: @_cdecl for import-as-member functions
//
extension CImplStruct {
@_objcImplementation @_cdecl("CImplStructStaticFunc1")
@implementation @_cdecl("CImplStructStaticFunc1")
static func staticFunc1(_: Int32) {
// FIXME: Add underlying support for this
// expected-error@-3 {{@_cdecl can only be applied to global functions}}