Skip to content

Commit 7f9eb4c

Browse files
authored
Merge pull request #83102 from gottesmm/release/6.2-revert
[6.2] Revert nonisolated(unsafe) closure inference
2 parents c9205fe + 348720b commit 7f9eb4c

File tree

3 files changed

+6
-308
lines changed

3 files changed

+6
-308
lines changed

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,8 +2490,7 @@ class PartitionOpTranslator {
24902490
}
24912491
}
24922492

2493-
if (auto isolationRegionInfo = SILIsolationInfo::get(pai);
2494-
isolationRegionInfo && !isolationRegionInfo.isDisconnected()) {
2493+
if (auto isolationRegionInfo = SILIsolationInfo::get(pai)) {
24952494
return translateIsolatedPartialApply(pai, isolationRegionInfo);
24962495
}
24972496

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 4 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -363,69 +363,6 @@ inferIsolationInfoForTempAllocStack(AllocStackInst *asi) {
363363
return SILIsolationInfo::get(targetOperand->getUser());
364364
}
365365

366-
static SILValue lookThroughNonVarDeclOwnershipInsts(SILValue v) {
367-
while (true) {
368-
if (auto *svi = dyn_cast<SingleValueInstruction>(v)) {
369-
if (isa<CopyValueInst>(svi)) {
370-
v = svi->getOperand(0);
371-
continue;
372-
}
373-
374-
if (auto *bbi = dyn_cast<BeginBorrowInst>(v)) {
375-
if (!bbi->isFromVarDecl()) {
376-
v = bbi->getOperand();
377-
continue;
378-
}
379-
return v;
380-
}
381-
382-
if (auto *mvi = dyn_cast<MoveValueInst>(v)) {
383-
if (!mvi->isFromVarDecl()) {
384-
v = mvi->getOperand();
385-
continue;
386-
}
387-
388-
return v;
389-
}
390-
}
391-
392-
return v;
393-
}
394-
}
395-
396-
/// See if \p pai has at least one nonisolated(unsafe) capture and that all
397-
/// captures are either nonisolated(unsafe) or sendable.
398-
static bool isPartialApplyNonisolatedUnsafe(PartialApplyInst *pai) {
399-
bool foundOneNonIsolatedUnsafe = false;
400-
for (auto &op : pai->getArgumentOperands()) {
401-
if (SILIsolationInfo::isSendableType(op.get()))
402-
continue;
403-
404-
// Normally we would not look through copy_value, begin_borrow, or
405-
// move_value since this is meant to find the inherent isolation of a
406-
// specific element. But since we are checking for captures rather
407-
// than the actual value itself (just for unsafe nonisolated
408-
// purposes), it is ok.
409-
//
410-
// E.x.: As an example of something we want to prevent, consider an
411-
// invocation of a nonisolated function that is a parameter to an
412-
// @MainActor function. That means from a region isolation
413-
// perspective, the function parameter is in the MainActor region, but
414-
// the actual function itself is not MainActor isolated, since the
415-
// function will not hop onto the main actor.
416-
//
417-
// TODO: We should use some of the shared infrastructure to find the
418-
// underlying value of op.get(). This is conservatively correct for
419-
// now.
420-
auto value = lookThroughNonVarDeclOwnershipInsts(op.get());
421-
if (!SILIsolationInfo::get(value).isUnsafeNonIsolated())
422-
return false;
423-
foundOneNonIsolatedUnsafe = true;
424-
}
425-
426-
return foundOneNonIsolatedUnsafe;
427-
}
428-
429366
SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
430367
if (auto fas = FullApplySite::isa(inst)) {
431368
// Before we do anything, see if we have a sending result. In such a case,
@@ -520,23 +457,12 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
520457
}
521458

522459
if (auto *pai = dyn_cast<PartialApplyInst>(inst)) {
523-
// Check if we have any captures and if the isolation info for all captures
524-
// are nonisolated(unsafe) or Sendable. In such a case, we consider the
525-
// partial_apply to be nonisolated(unsafe). We purposely do not do this if
526-
// the partial_apply does not have any parameters just out of paranoia... we
527-
// shouldn't have such a partial_apply emitted by SILGen (it should use a
528-
// thin to thick function or something like that)... but in that case since
529-
// we do not have any nonisolated(unsafe), it doesn't make sense to
530-
// propagate nonisolated(unsafe).
531-
bool partialApplyIsNonIsolatedUnsafe = isPartialApplyNonisolatedUnsafe(pai);
532-
533460
if (auto *ace = pai->getLoc().getAsASTNode<AbstractClosureExpr>()) {
534461
auto actorIsolation = ace->getActorIsolation();
535462

536463
if (actorIsolation.isGlobalActor()) {
537464
return SILIsolationInfo::getGlobalActorIsolated(
538-
pai, actorIsolation.getGlobalActor())
539-
.withUnsafeNonIsolated(partialApplyIsNonIsolatedUnsafe);
465+
pai, actorIsolation.getGlobalActor());
540466
}
541467

542468
if (actorIsolation.isActorInstanceIsolated()) {
@@ -559,16 +485,13 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
559485
if (auto *fArg = dyn_cast<SILFunctionArgument>(
560486
actualIsolatedValue.getValue())) {
561487
if (auto info =
562-
SILIsolationInfo::getActorInstanceIsolated(pai, fArg)
563-
.withUnsafeNonIsolated(
564-
partialApplyIsNonIsolatedUnsafe))
488+
SILIsolationInfo::getActorInstanceIsolated(pai, fArg))
565489
return info;
566490
}
567491
}
568492

569493
return SILIsolationInfo::getActorInstanceIsolated(
570-
pai, actorInstance, actorIsolation.getActor())
571-
.withUnsafeNonIsolated(partialApplyIsNonIsolatedUnsafe);
494+
pai, actorInstance, actorIsolation.getActor());
572495
}
573496

574497
// For now, if we do not have an actor instance, just create an actor
@@ -582,16 +505,12 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
582505
//
583506
// TODO: How do we want to resolve this.
584507
return SILIsolationInfo::getPartialApplyActorInstanceIsolated(
585-
pai, actorIsolation.getActor())
586-
.withUnsafeNonIsolated(partialApplyIsNonIsolatedUnsafe);
508+
pai, actorIsolation.getActor());
587509
}
588510

589511
assert(actorIsolation.getKind() != ActorIsolation::Erased &&
590512
"Implement this!");
591513
}
592-
593-
if (partialApplyIsNonIsolatedUnsafe)
594-
return SILIsolationInfo::getDisconnected(partialApplyIsNonIsolatedUnsafe);
595514
}
596515

597516
// See if the memory base is a ref_element_addr from an address. If so, add

test/Concurrency/transfernonsendable_nonisolatedunsafe.swift

Lines changed: 1 addition & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// MARK: Declarations //
1313
////////////////////////
1414

15-
class NonSendableKlass {
15+
class NonSendableKlass { // expected-complete-note 98{{}}
1616
var field: NonSendableKlass? = nil
1717
}
1818

@@ -823,223 +823,3 @@ actor ActorContainingSendableStruct {
823823
}
824824

825825

826-
////////////////////
827-
// MARK: Closures //
828-
////////////////////
829-
830-
func closureTests() async {
831-
func sendingClosure(_ x: sending () -> ()) {
832-
}
833-
834-
func testLetOneNSVariableError() async {
835-
let x = NonSendableKlass()
836-
sendingClosure { _ = x } // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
837-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
838-
sendingClosure { _ = x } // expected-note {{access can happen concurrently}}
839-
}
840-
841-
func testLetNonIsolatedUnsafeNSVariableNoError() async {
842-
nonisolated(unsafe) let x = NonSendableKlass()
843-
sendingClosure { _ = x }
844-
sendingClosure { _ = x }
845-
}
846-
847-
func testLetOneNSVariableSVariableError() async {
848-
let x = NonSendableKlass()
849-
let y = CustomActorInstance()
850-
sendingClosure { // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
851-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
852-
_ = x
853-
_ = y
854-
}
855-
sendingClosure { // expected-note {{access can happen concurrently}}
856-
_ = x
857-
_ = y
858-
}
859-
}
860-
861-
func testLetNonIsolatedUnsafeNSSVariableNoError() async {
862-
nonisolated(unsafe) let x = NonSendableKlass()
863-
let y = CustomActorInstance()
864-
sendingClosure {
865-
_ = x
866-
_ = y
867-
}
868-
sendingClosure {
869-
_ = x
870-
_ = y
871-
}
872-
}
873-
874-
func testLetTwoNSVariableError() async {
875-
let x = NonSendableKlass()
876-
let y = NonSendableKlass()
877-
sendingClosure { // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
878-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
879-
_ = x
880-
_ = y
881-
}
882-
sendingClosure { // expected-note {{access can happen concurrently}}
883-
_ = x
884-
_ = y
885-
}
886-
}
887-
888-
func testLetTwoNSVariableError2() async {
889-
nonisolated(unsafe) let x = NonSendableKlass()
890-
let y = NonSendableKlass()
891-
sendingClosure { // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
892-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
893-
_ = x
894-
_ = y
895-
}
896-
sendingClosure { // expected-note {{access can happen concurrently}}
897-
_ = x
898-
_ = y
899-
}
900-
}
901-
902-
func testLetTwoNSVariableError3() async {
903-
nonisolated(unsafe) let x = NonSendableKlass()
904-
nonisolated(unsafe) let y = NonSendableKlass()
905-
sendingClosure {
906-
_ = x
907-
_ = y
908-
}
909-
sendingClosure {
910-
_ = x
911-
_ = y
912-
}
913-
}
914-
915-
func testVarOneNSVariableError() async {
916-
var x = NonSendableKlass()
917-
x = NonSendableKlass()
918-
919-
sendingClosure { _ = x } // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
920-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
921-
sendingClosure { _ = x } // expected-note {{access can happen concurrently}}
922-
}
923-
924-
func testVarNonIsolatedUnsafeNSVariableNoError() async {
925-
nonisolated(unsafe) var x = NonSendableKlass()
926-
x = NonSendableKlass()
927-
928-
sendingClosure { _ = x }
929-
sendingClosure { _ = x }
930-
}
931-
932-
func testVarOneNSVariableSVariableError() async {
933-
var x = NonSendableKlass()
934-
x = NonSendableKlass()
935-
var y = CustomActorInstance()
936-
y = CustomActorInstance()
937-
sendingClosure { // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
938-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
939-
_ = x
940-
_ = y
941-
}
942-
sendingClosure { // expected-note {{access can happen concurrently}}
943-
_ = x
944-
_ = y
945-
}
946-
}
947-
948-
func testVarNonIsolatedUnsafeNSSVariableNoError() async {
949-
nonisolated(unsafe) var x = NonSendableKlass()
950-
x = NonSendableKlass()
951-
var y = CustomActorInstance()
952-
y = CustomActorInstance()
953-
sendingClosure {
954-
_ = x
955-
_ = y
956-
}
957-
sendingClosure {
958-
_ = x
959-
_ = y
960-
}
961-
}
962-
963-
func testVarTwoNSVariableError() async {
964-
var x = NonSendableKlass()
965-
x = NonSendableKlass()
966-
var y = NonSendableKlass()
967-
y = NonSendableKlass()
968-
sendingClosure { // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
969-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
970-
_ = x
971-
_ = y
972-
}
973-
sendingClosure { // expected-note {{access can happen concurrently}}
974-
_ = x
975-
_ = y
976-
}
977-
}
978-
979-
func testVarTwoNSVariableError2() async {
980-
nonisolated(unsafe) var x = NonSendableKlass()
981-
x = NonSendableKlass()
982-
var y = NonSendableKlass()
983-
y = NonSendableKlass()
984-
sendingClosure { // expected-warning {{sending value of non-Sendable type '() -> ()' risks causing data races}}
985-
// expected-note @-1 {{Passing value of non-Sendable type '() -> ()' as a 'sending' argument to local function 'sendingClosure' risks causing races in between local and caller code}}
986-
_ = x
987-
_ = y
988-
}
989-
sendingClosure { // expected-note {{access can happen concurrently}}
990-
_ = x
991-
_ = y
992-
}
993-
}
994-
995-
func testVarTwoNSVariableError3() async {
996-
nonisolated(unsafe) var x = NonSendableKlass()
997-
x = NonSendableKlass()
998-
nonisolated(unsafe) var y = NonSendableKlass()
999-
y = NonSendableKlass()
1000-
sendingClosure {
1001-
_ = x
1002-
_ = y
1003-
}
1004-
sendingClosure {
1005-
_ = x
1006-
_ = y
1007-
}
1008-
}
1009-
1010-
func testWithTaskDetached() async {
1011-
let x1 = NonSendableKlass()
1012-
Task.detached { _ = x1 } // expected-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
1013-
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to static method 'detached(name:priority:operation:)' risks causing races in between local and caller code}}
1014-
Task.detached { _ = x1 } // expected-note {{access can happen concurrently}}
1015-
1016-
nonisolated(unsafe) let x2 = NonSendableKlass()
1017-
Task.detached { _ = x2 }
1018-
Task.detached { _ = x2 }
1019-
1020-
nonisolated(unsafe) let x3a = NonSendableKlass()
1021-
nonisolated(unsafe) let x3b = NonSendableKlass()
1022-
Task.detached { _ = x3a; _ = x3b }
1023-
Task.detached { _ = x3a; _ = x3b }
1024-
1025-
nonisolated(unsafe) let x4a = NonSendableKlass()
1026-
let x4b = NonSendableKlass()
1027-
Task.detached { _ = x4a; _ = x4b } // expected-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
1028-
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to static method 'detached(name:priority:operation:)' risks causing races in between local and caller code}}
1029-
Task.detached { _ = x4a; _ = x4b } // expected-note {{access can happen concurrently}}
1030-
}
1031-
1032-
// The reason why this works is that we do not infer nonisolated(unsafe)
1033-
// passed the begin_borrow [var_decl] of y. So we think the closure is
1034-
// nonisolated(unsafe), but its uses via the begin_borrow [var_decl] is
1035-
// not.
1036-
func testNamedClosure() async {
1037-
nonisolated(unsafe) let x = NonSendableKlass()
1038-
let y = {
1039-
_ = x
1040-
}
1041-
sendingClosure(y) // expected-warning {{sending 'y' risks causing data races}}
1042-
// expected-note @-1 {{'y' used after being passed as a 'sending' parameter}}
1043-
sendingClosure(y) // expected-note {{access can happen concurrently}}
1044-
}
1045-
}

0 commit comments

Comments
 (0)