Skip to content

Commit 0382996

Browse files
authored
Merge pull request #75542 from gottesmm/release/6.0-rdar132347404
[6.0][region-isolation] Do not ignore non-trivial results that are Sendable to be more permissive in the face of lazy typechecker issues.
2 parents d454e93 + 4d2f337 commit 0382996

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
@@ -2888,9 +2888,6 @@ CONSTANT_TRANSLATION(VectorInst, Asserting)
28882888

28892889
#define IGNORE_IF_SENDABLE_RESULT_ASSIGN_OTHERWISE(INST) \
28902890
TranslationSemantics PartitionOpTranslator::visit##INST(INST *inst) { \
2891-
if (!isNonSendableType(inst->getType())) { \
2892-
return TranslationSemantics::Ignored; \
2893-
} \
28942891
return TranslationSemantics::Assign; \
28952892
}
28962893

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

29282933
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
@@ -872,8 +872,8 @@ func letSendableTrivialLetStructFieldTest() async {
872872
await transferToMain(test) // expected-tns-warning {{sending 'test' risks causing data races}}
873873
// 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}}
874874
// expected-complete-warning @-2 {{passing argument of non-sendable type 'StructFieldTests' into main actor-isolated context may introduce data races}}
875-
_ = test.letSendableTrivial
876-
useValue(test) // expected-tns-note {{access can happen concurrently}}
875+
_ = test.letSendableTrivial // expected-tns-note {{access can happen concurrently}}
876+
useValue(test)
877877
}
878878

879879
func letSendableNonTrivialLetStructFieldTest() async {
@@ -941,20 +941,20 @@ func letNonSendableNonTrivialLetStructFieldClosureTest() async {
941941
await transferToMain(test) // expected-tns-warning {{sending 'test' risks causing data races}}
942942
// 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}}
943943
// expected-complete-warning @-2 {{passing argument of non-sendable type 'StructFieldTests' into main actor-isolated context may introduce data races}}
944-
let z = test.letSendableNonTrivial
944+
let z = test.letSendableNonTrivial // expected-tns-note {{access can happen concurrently}}
945945
_ = z
946946
let z2 = test.varSendableNonTrivial
947947
_ = z2
948-
useValue(test) // expected-tns-note {{access can happen concurrently}}
948+
useValue(test)
949949
}
950950

951951
func varSendableTrivialLetStructFieldTest() async {
952952
let test = StructFieldTests()
953953
await transferToMain(test) // expected-tns-warning {{sending 'test' risks causing data races}}
954954
// 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}}
955955
// expected-complete-warning @-2 {{passing argument of non-sendable type 'StructFieldTests' into main actor-isolated context may introduce data races}}
956-
_ = test.varSendableTrivial
957-
useValue(test) // expected-tns-note {{access can happen concurrently}}
956+
_ = test.varSendableTrivial // expected-tns-note {{access can happen concurrently}}
957+
useValue(test)
958958
}
959959

960960
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)