Skip to content

Commit 72ad780

Browse files
authored
Merge pull request #75541 from gottesmm/pr-7133549c90f98b7c9be71f80b74a97d088aa62f2
[region-isolation] Do not ignore non-trivial results that are Sendable to be more permissive in the face of lazy typechecker issues.
2 parents 741cd47 + 8604480 commit 72ad780

File tree

3 files changed

+102
-13
lines changed

3 files changed

+102
-13
lines changed

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,9 +2891,6 @@ CONSTANT_TRANSLATION(VectorInst, Asserting)
28912891

28922892
#define IGNORE_IF_SENDABLE_RESULT_ASSIGN_OTHERWISE(INST) \
28932893
TranslationSemantics PartitionOpTranslator::visit##INST(INST *inst) { \
2894-
if (!isNonSendableType(inst->getType())) { \
2895-
return TranslationSemantics::Ignored; \
2896-
} \
28972894
return TranslationSemantics::Assign; \
28982895
}
28992896

@@ -2922,10 +2919,18 @@ IGNORE_IF_SENDABLE_RESULT_ASSIGN_OTHERWISE(StructExtractInst)
29222919
return TranslationSemantics::Require; \
29232920
} \
29242921
\
2925-
if (isResultNonSendable) \
2926-
return TranslationSemantics::AssignFresh; \
2927-
\
2928-
return TranslationSemantics::Ignored; \
2922+
/* We always use assign fresh here regardless of whether or not a */ \
2923+
/* type is sendable. */ \
2924+
/* */ \
2925+
/* DISCUSSION: Since the typechecker is lazy, if there is a bug */ \
2926+
/* that causes us to not look up enough type information it is */ \
2927+
/* possible for a type to move from being Sendable to being */ \
2928+
/* non-Sendable. For example, we could call isNonSendableType and */ \
2929+
/* get that the type is non-Sendable, but as a result of calling */ \
2930+
/* that API, the type checker could get more information that the */ \
2931+
/* next time we call isNonSendableType, we will get that the type */ \
2932+
/* is non-Sendable. */ \
2933+
return TranslationSemantics::AssignFresh; \
29292934
}
29302935

29312936
LOOKTHROUGH_IF_NONSENDABLE_RESULT_AND_OPERAND(UncheckedTrivialBitCastInst)

test/Concurrency/transfernonsendable.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -878,8 +878,8 @@ func letSendableTrivialLetStructFieldTest() async {
878878
await transferToMain(test) // expected-tns-warning {{sending 'test' risks causing data races}}
879879
// expected-tns-note @-1 {{sending 'test' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and local nonisolated uses}}
880880
// expected-complete-warning @-2 {{passing argument of non-sendable type 'StructFieldTests' into main actor-isolated context may introduce data races}}
881-
_ = test.letSendableTrivial
882-
useValue(test) // expected-tns-note {{access can happen concurrently}}
881+
_ = test.letSendableTrivial // expected-tns-note {{access can happen concurrently}}
882+
useValue(test)
883883
}
884884

885885
func letSendableNonTrivialLetStructFieldTest() async {
@@ -947,20 +947,20 @@ func letNonSendableNonTrivialLetStructFieldClosureTest() async {
947947
await transferToMain(test) // expected-tns-warning {{sending 'test' risks causing data races}}
948948
// expected-tns-note @-1 {{sending 'test' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and local nonisolated uses}}
949949
// expected-complete-warning @-2 {{passing argument of non-sendable type 'StructFieldTests' into main actor-isolated context may introduce data races}}
950-
let z = test.letSendableNonTrivial
950+
let z = test.letSendableNonTrivial // expected-tns-note {{access can happen concurrently}}
951951
_ = z
952952
let z2 = test.varSendableNonTrivial
953953
_ = z2
954-
useValue(test) // expected-tns-note {{access can happen concurrently}}
954+
useValue(test)
955955
}
956956

957957
func varSendableTrivialLetStructFieldTest() async {
958958
let test = StructFieldTests()
959959
await transferToMain(test) // expected-tns-warning {{sending 'test' risks causing data races}}
960960
// expected-tns-note @-1 {{sending 'test' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and local nonisolated uses}}
961961
// expected-complete-warning @-2 {{passing argument of non-sendable type 'StructFieldTests' into main actor-isolated context may introduce data races}}
962-
_ = test.varSendableTrivial
963-
useValue(test) // expected-tns-note {{access can happen concurrently}}
962+
_ = test.varSendableTrivial // expected-tns-note {{access can happen concurrently}}
963+
useValue(test)
964964
}
965965

966966
func varSendableNonTrivialLetStructFieldTest() async {
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/src)
3+
// RUN: %empty-directory(%t/sdk)
4+
// RUN: %empty-directory(%t/sdk/ObjCAPI)
5+
// RUN: %empty-directory(%t/sdk/SwiftAPI)
6+
// RUN: %empty-directory(%t/compile)
7+
// RUN: split-file %s %t/src
8+
9+
// Build Objective-C lib
10+
// RUN: %target-clang -dynamiclib %t/src/ObjCAPI.m -I %t/src -o %t/sdk/ObjCAPI/libObjCAPI.dylib -lobjc
11+
// RUN: cp %t/src/ObjCAPI.modulemap %t/sdk/ObjCAPI/module.modulemap
12+
// RUN: cp %t/src/ObjCAPI.h %t/sdk/ObjCAPI/ObjCAPI.h
13+
14+
// Build the swift part of API
15+
// RUN: %target-swiftc_driver -emit-library -emit-module-path %t/sdk/SwiftAPI/SwiftAPI.swiftmodule %t/src/SwiftAPI.swift -parse-as-library -I %t/sdk -swift-version 6 -module-name SwiftAPI -enable-library-evolution
16+
17+
// Now compile against the API.
18+
// RUN: %target-swift-frontend -emit-sil -o /dev/null -I %t/sdk/SwiftAPI -I %t/sdk/ObjCAPI %t/src/main.swift -swift-version 6
19+
20+
// REQUIRES: asserts
21+
// REQUIRES: concurrency
22+
// REQUIRES: objc_interop
23+
24+
// Test
25+
26+
//--- ObjCAPI.modulemap
27+
28+
module ObjCAPI {
29+
header "ObjCAPI.h"
30+
}
31+
32+
//--- ObjCAPI.h
33+
34+
#define NS_SWIFT_SENDABLE __attribute__((swift_attr("@Sendable")))
35+
#define NS_SWIFT_NONSENDABLE __attribute__((swift_attr("@_nonSendable")))
36+
37+
NS_SWIFT_NONSENDABLE
38+
@interface MyParentClass
39+
@end
40+
41+
NS_SWIFT_SENDABLE
42+
@interface MySubClass : MyParentClass
43+
@end
44+
45+
//--- ObjCAPI.m
46+
47+
#include "ObjCAPI.h"
48+
49+
@implementation MyParentClass
50+
@end
51+
52+
@implementation MySubClass
53+
@end
54+
55+
//--- SwiftAPI.swift
56+
57+
@_exported import ObjCAPI // Clang module
58+
59+
public struct Measurement<T : MyParentClass> {
60+
/// The unit component of the `Measurement`.
61+
public let unit: T
62+
63+
public var count: Int { 0 }
64+
}
65+
66+
extension Measurement : Sendable where T : Sendable {}
67+
68+
//--- main.swift
69+
70+
public import SwiftAPI
71+
72+
public enum MarketplaceKitError : Sendable {
73+
case first
74+
case second(Measurement<MySubClass>)
75+
76+
public var description: String {
77+
switch self {
78+
case .first:
79+
return "first"
80+
case .second(let value):
81+
return "\(value.count)"
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)