Skip to content

Commit c6e3c71

Browse files
authored
Merge pull request swiftlang#74575 from xedin/objc-and-sendable-fixes-6.0
[6.0][ClangImporter/SILGen] A couple of fixes for ObjC and Sendable interaction
2 parents d089f83 + 9009e1f commit c6e3c71

File tree

6 files changed

+113
-7
lines changed

6 files changed

+113
-7
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7330,10 +7330,10 @@ std::optional<GenericParamList *> SwiftDeclConverter::importObjCGenericParams(
73307330
TypeLoc::withoutLoc(proto->getDeclaredInterfaceType()));
73317331
}
73327332
}
7333-
if (inherited.empty()) {
7334-
inherited.push_back(
7335-
TypeLoc::withoutLoc(Impl.SwiftContext.getAnyObjectConstraint()));
7336-
}
7333+
7334+
inherited.push_back(
7335+
TypeLoc::withoutLoc(Impl.SwiftContext.getAnyObjectConstraint()));
7336+
73377337
genericParamDecl->setInherited(Impl.SwiftContext.AllocateCopy(inherited));
73387338

73397339
genericParams.push_back(genericParamDecl);

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,8 +1170,8 @@ static ManagedValue emitCBridgedToNativeValue(
11701170
.getAsSingleValue(SGF, loc);
11711171

11721172
// Convert to the marker existential if necessary.
1173-
auto anyType = SGF.getASTContext().getAnyExistentialType();
1174-
if (nativeType != anyType) {
1173+
if (!v.isInContext()) {
1174+
auto anyType = SGF.getASTContext().getAnyExistentialType();
11751175
v = SGF.emitTransformedValue(loc, v, anyType, nativeType);
11761176
}
11771177

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -emit-silgen %t/main.swift -import-objc-header %t/Test.h | %FileCheck %t/main.swift
5+
6+
// REQUIRES: objc_interop
7+
// REQUIRES: concurrency
8+
9+
10+
// rdar://127520993
11+
12+
//--- Test.h
13+
#import <Foundation/Foundation.h>
14+
15+
#define SWIFT_SENDABLE __attribute__((__swift_attr__("@Sendable")))
16+
17+
@interface Test<N : id SWIFT_SENDABLE> : NSObject
18+
- (void)luckWithNumber:(nullable N)number;
19+
@end
20+
21+
//--- main.swift
22+
import Foundation
23+
24+
Test<NSNumber>().luck(withNumber: 5)
25+
// CHECK-LABEL: sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32
26+
// CHECK: [[NS_NUMBER_INIT:%.*]] = function_ref @$sSo8NSNumberC10FoundationE14integerLiteralABSi_tcfC : $@convention(method) (Int, @thick NSNumber.Type) -> @owned NSNumber
27+
// CHECK-NEXT: [[NS_NUMBER:%.*]] = apply [[NS_NUMBER_INIT]]({{.*}}) : $@convention(method) (Int, @thick NSNumber.Type) -> @owned NSNumber
28+
// CHECK-NEXT: [[OPT_NS_NUMBER:%.*]] = enum $Optional<NSNumber>, #Optional.some!enumelt, [[NS_NUMBER]] : $NSNumber
29+
// CHECK-NEXT: [[LUCK_METHOD_REF:%.*]] = objc_method %4 : $Test<NSNumber>, #Test.luck!foreign : <N where N : AnyObject, N : Sendable> (Test<N>) -> (N?) -> (), $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject, τ_0_0 : Sendable> (Optional<τ_0_0>, Test<τ_0_0>) -> ()
30+
// CHECK-NEXT: %14 = apply [[LUCK_METHOD_REF]]<NSNumber>([[OPT_NS_NUMBER]], {{.*}}) : $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject, τ_0_0 : Sendable> (Optional<τ_0_0>, Test<τ_0_0>) -> ()
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-clang %t/Test.m -c -o %t/Test.o
5+
// RUN: %target-build-swift %t/main.swift -import-objc-header %t/Test.h %t/Test.o -o %t/main
6+
// RUN: %target-codesign %t/main
7+
// RUN: %target-run %t/main | %FileCheck %t/main.swift
8+
9+
// REQUIRES: executable_test
10+
// REQUIRES: objc_interop
11+
// REQUIRES: concurrency
12+
// REQUIRES: OS=macosx
13+
14+
// rdar://127520993
15+
16+
//--- Test.h
17+
#import <Foundation/Foundation.h>
18+
19+
#define SWIFT_SENDABLE __attribute__((__swift_attr__("@Sendable")))
20+
21+
@interface Test<N : id SWIFT_SENDABLE> : NSObject
22+
- (void)luckWithNumber:(nullable N)number;
23+
@end
24+
25+
//--- Test.m
26+
#import "Test.h"
27+
28+
static void NSPrint(NSString *format, ...)
29+
{
30+
va_list args;
31+
32+
va_start(args, format);
33+
NSString *string = [[NSString alloc] initWithFormat:format arguments:args];
34+
va_end(args);
35+
36+
fprintf(stdout, "%s\n", [string UTF8String]);
37+
38+
#if !__has_feature(objc_arc)
39+
[string release];
40+
#endif
41+
}
42+
43+
@implementation Test
44+
45+
- (void)luckWithNumber:(id)number
46+
{
47+
NSPrint(@"Lucky number: %@", number);
48+
}
49+
50+
@end
51+
52+
//--- main.swift
53+
Test<NSNumber>().luck(withNumber: 5)
54+
// CHECK: Lucky number: 5

test/SILGen/Inputs/objc_bridging_sendable.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
@interface NSBlah: NSObject
44
- (void) takeSendable: (id __attribute__((swift_attr("@Sendable")))) x;
5-
@property (readonly) id __attribute__((swift_attr("@Sendable"))) x;
5+
@property(readonly) id __attribute__((swift_attr("@Sendable"))) x;
6+
- (nullable __attribute__((swift_attr("@Sendable"))) id)test:(NSError *_Nullable __autoreleasing * _Nullable)error;
67
@end

test/SILGen/objc_bridging_sendable.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,25 @@ public func passSendableToObjC(_ s: Sendable) {
1212

1313
public func useSendableProperty(_ ns: NSBlah) {
1414
_ = ns.x
15+
let _: (Int, Any, String, [Any]) = (42, ns.x, "", [1, 2, 3])
16+
}
17+
18+
// CHECK-LABEL: sil private [ossa] @$s22objc_bridging_sendable23test_use_of_buffer_inityyKFypSo6NSBlahCKXEfU_ : $@convention(thin) @substituted <τ_0_0> (@guaranteed NSBlah) -> (@out τ_0_0, @error any Error) for <Any>
19+
// CHECK: bb0(%0 : $*Any, %1 : @guaranteed $NSBlah):
20+
// CHECK: [[TEST_REF:%.*]] = objc_method %1 : $NSBlah, #NSBlah.test!foreign : (NSBlah) -> () throws -> any Sendable, $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, NSBlah) -> @autoreleased Optional<AnyObject>
21+
// CHECK: [[RESULT:%.*]] = apply [[TEST_REF]]({{.*}}, %1) : $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, NSBlah) -> @autoreleased Optional<AnyObject>
22+
// CHECK: switch_enum [[RESULT]] : $Optional<AnyObject>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
23+
// CHECK: bb1([[SUCCESS:%.*]] : @owned $AnyObject)
24+
// CHECK-NEXT: [[OPT_RESULT_VALUE:%.*]] = unchecked_ref_cast [[SUCCESS]] : $AnyObject to $Optional<AnyObject>
25+
// CHECK-NEXT: // function_ref _bridgeAnyObjectToAny(_:)
26+
// CHECK-NEXT: [[BRIDGE_INTRINSIC_REF:%.*]] = function_ref @$ss018_bridgeAnyObjectToB0yypyXlSgF : $@convention(thin) (@guaranteed Optional<AnyObject>) -> @out Any
27+
// CHECK-NEXT: apply [[BRIDGE_INTRINSIC_REF]](%0, [[OPT_RESULT_VALUE]]) : $@convention(thin) (@guaranteed Optional<AnyObject>) -> @out Any
28+
func test_use_of_buffer_init() throws {
29+
func test<T: Sendable>(_: (NSBlah) throws -> T) rethrows -> T {
30+
fatalError()
31+
}
32+
33+
let _: Any = try test {
34+
try $0.test()
35+
}
1536
}

0 commit comments

Comments
 (0)