Skip to content

Commit 1932d07

Browse files
authored
Merge pull request #78650 from xedin/rdar-142567811
[Sema] Emit dynamic actor isolation checks for derived protocol witnesses
2 parents ca7e736 + a30bcff commit 1932d07

File tree

5 files changed

+133
-5
lines changed

5 files changed

+133
-5
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "TypeCheckObjC.h"
2222
#include "TypeCheckType.h"
2323
#include "TypeChecker.h"
24+
#include "DerivedConformances.h"
2425
#include "swift/AST/ASTMangler.h"
2526
#include "swift/AST/ASTPrinter.h"
2627
#include "swift/AST/AvailabilityInference.h"
@@ -1728,6 +1729,15 @@ bool swift::hasLetStoredPropertyWithInitialValue(NominalTypeDecl *nominal) {
17281729
});
17291730
}
17301731

1732+
bool swift::addNonIsolatedToSynthesized(DerivedConformance &derived,
1733+
ValueDecl *value) {
1734+
if (auto *conformance = derived.Conformance) {
1735+
if (conformance && conformance->isPreconcurrency())
1736+
return false;
1737+
}
1738+
return addNonIsolatedToSynthesized(derived.Nominal, value);
1739+
}
1740+
17311741
bool swift::addNonIsolatedToSynthesized(NominalTypeDecl *nominal,
17321742
ValueDecl *value) {
17331743
if (!getActorIsolation(nominal).isActorIsolated())

lib/Sema/CodeSynthesis.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class ParamDecl;
4141
class Type;
4242
class ValueDecl;
4343
class VarDecl;
44+
class DerivedConformance;
4445

4546
enum class SelfAccessorKind {
4647
/// We're building a derived accessor on top of whatever this
@@ -85,6 +86,11 @@ ValueDecl *getProtocolRequirement(ProtocolDecl *protocol, Identifier name);
8586
// with an initial value.
8687
bool hasLetStoredPropertyWithInitialValue(NominalTypeDecl *nominal);
8788

89+
/// Add 'nonisolated' to the synthesized declaration for a derived
90+
/// conformance when needed. Returns true if an attribute was added.
91+
bool addNonIsolatedToSynthesized(DerivedConformance &conformance,
92+
ValueDecl *value);
93+
8894
/// Add 'nonisolated' to the synthesized declaration when needed. Returns true
8995
/// if an attribute was added.
9096
bool addNonIsolatedToSynthesized(NominalTypeDecl *nominal, ValueDecl *value);

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,7 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) {
12541254
encodeDecl->getAttrs().add(attr);
12551255
}
12561256

1257-
addNonIsolatedToSynthesized(derived.Nominal, encodeDecl);
1257+
addNonIsolatedToSynthesized(derived, encodeDecl);
12581258

12591259
encodeDecl->copyFormalAccessFrom(derived.Nominal,
12601260
/*sourceIsParentContext*/ true);
@@ -1906,7 +1906,7 @@ static ValueDecl *deriveDecodable_init(DerivedConformance &derived) {
19061906
initDecl->getAttrs().add(reqAttr);
19071907
}
19081908

1909-
addNonIsolatedToSynthesized(derived.Nominal, initDecl);
1909+
addNonIsolatedToSynthesized(derived, initDecl);
19101910

19111911
initDecl->copyFormalAccessFrom(derived.Nominal,
19121912
/*sourceIsParentContext*/ true);

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ deriveEquatable_eq(
428428
return nullptr;
429429
}
430430

431-
addNonIsolatedToSynthesized(derived.Nominal, eqDecl);
431+
addNonIsolatedToSynthesized(derived, eqDecl);
432432

433433
eqDecl->setBodySynthesizer(bodySynthesizer);
434434

@@ -553,7 +553,7 @@ deriveHashable_hashInto(
553553
/*sourceIsParentContext=*/true);
554554

555555
// The derived hash(into:) for an actor must be non-isolated.
556-
if (!addNonIsolatedToSynthesized(derived.Nominal, hashDecl) &&
556+
if (!addNonIsolatedToSynthesized(derived, hashDecl) &&
557557
derived.Nominal->isActor())
558558
hashDecl->getAttrs().add(
559559
new (C) NonisolatedAttr(/*unsafe*/ false, /*implicit*/ true));
@@ -913,7 +913,7 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) {
913913
hashValueDecl->setAccessors(SourceLoc(), {getterDecl}, SourceLoc());
914914

915915
// The derived hashValue of an actor must be nonisolated.
916-
if (!addNonIsolatedToSynthesized(derived.Nominal, hashValueDecl) &&
916+
if (!addNonIsolatedToSynthesized(derived, hashValueDecl) &&
917917
derived.Nominal->isActor())
918918
hashValueDecl->getAttrs().add(
919919
new (C) NonisolatedAttr(/*unsafe*/ false, /*implicit*/ true));

test/SILGen/preconcurrency_conformances.swift

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,71 @@ struct PreconcurrencyAppliesToParentToo : @preconcurrency Child {
309309
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
310310
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
311311

312+
@available(*, unavailable)
313+
extension NotSendable: Sendable {}
314+
315+
struct NotSendable: Equatable, Hashable {
316+
}
317+
318+
@MainActor
319+
struct TestDerivedEquatable : @preconcurrency Equatable {
320+
var x: NotSendable
321+
}
322+
323+
// protocol witness for static Equatable.== infix(_:_:) in conformance TestDerivedEquatable
324+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances20TestDerivedEquatableVSQAASQ2eeoiySbx_xtFZTW
325+
// CHECK: [[MAIN_ACTOR:%.*]] = begin_borrow {{.*}} : $MainActor
326+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
327+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
328+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
329+
330+
@MainActor
331+
struct TestDerivedHashable : @preconcurrency Hashable {
332+
var x: NotSendable
333+
}
334+
335+
// protocol witness for Hashable.hashValue.getter in conformance TestDerivedHashable
336+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances19TestDerivedHashableVSHAASH9hashValueSivgTW
337+
// CHECK: [[MAIN_ACTOR:%.*]] = begin_borrow {{.*}} : $MainActor
338+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
339+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
340+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
341+
342+
// protocol witness for Hashable.hash(into:) in conformance TestDerivedHashable
343+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances19TestDerivedHashableVSHAASH4hash4intoys6HasherVz_tFTW
344+
// CHECK: [[MAIN_ACTOR:%.*]] = begin_borrow {{.*}} : $MainActor
345+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
346+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
347+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
348+
349+
// protocol witness for static Equatable.== infix(_:_:) in conformance TestDerivedHashable
350+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances19TestDerivedHashableVSQAASQ2eeoiySbx_xtFZTW
351+
// CHECK: [[MAIN_ACTOR:%.*]] = begin_borrow {{.*}} : $MainActor
352+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
353+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
354+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
355+
356+
extension NotSendable : Codable {}
357+
358+
@MainActor
359+
struct TestDerivedCodable : @preconcurrency Codable {
360+
var x: NotSendable
361+
}
362+
363+
// protocol witness for Decodable.init(from:) in conformance TestDerivedCodable
364+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances18TestDerivedCodableVSeAASe4fromxs7Decoder_p_tKcfCTW
365+
// CHECK: [[MAIN_ACTOR:%.*]] = begin_borrow {{.*}} : $MainActor
366+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
367+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
368+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
369+
370+
// protocol witness for Encodable.encode(to:) in conformance TestDerivedCodable
371+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances18TestDerivedCodableVSEAASE6encode2toys7Encoder_p_tKFTW
372+
// CHECK: [[MAIN_ACTOR:%.*]] = begin_borrow {{.*}} : $MainActor
373+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
374+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
375+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
376+
312377
//--- checks_disabled.swift
313378
protocol P {
314379
associatedtype T
@@ -498,3 +563,50 @@ struct PreconcurrencyAppliesToParentToo : @preconcurrency Child {
498563
// protocol witness for Parent.a() in conformance PreconcurrencyAppliesToParentToo
499564
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances32PreconcurrencyAppliesToParentTooVAA0F0A2aDP1ayyFTW : $@convention(witness_method: Parent) (@in_guaranteed PreconcurrencyAppliesToParentToo) -> ()
500565
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
566+
567+
@available(*, unavailable)
568+
extension NotSendable: Sendable {}
569+
570+
struct NotSendable: Equatable, Hashable {
571+
}
572+
573+
@MainActor
574+
struct TestDerivedEquatable : @preconcurrency Equatable {
575+
var x: NotSendable
576+
}
577+
578+
// protocol witness for static Equatable.== infix(_:_:) in conformance TestDerivedEquatable
579+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances20TestDerivedEquatableVSQAASQ2eeoiySbx_xtFZTW
580+
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
581+
582+
@MainActor
583+
struct TestDerivedHashable : @preconcurrency Hashable {
584+
var x: NotSendable
585+
}
586+
587+
// protocol witness for Hashable.hashValue.getter in conformance TestDerivedHashable
588+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances19TestDerivedHashableVSHAASH9hashValueSivgTW
589+
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
590+
591+
// protocol witness for Hashable.hash(into:) in conformance TestDerivedHashable
592+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances19TestDerivedHashableVSHAASH4hash4intoys6HasherVz_tFTW
593+
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
594+
595+
// protocol witness for static Equatable.== infix(_:_:) in conformance TestDerivedHashable
596+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances19TestDerivedHashableVSQAASQ2eeoiySbx_xtFZTW
597+
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
598+
599+
extension NotSendable : Codable {}
600+
601+
@MainActor
602+
struct TestDerivedCodable : @preconcurrency Codable {
603+
var x: NotSendable
604+
}
605+
606+
// protocol witness for Decodable.init(from:) in conformance TestDerivedCodable
607+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances18TestDerivedCodableVSeAASe4fromxs7Decoder_p_tKcfCTW
608+
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
609+
610+
// protocol witness for Encodable.encode(to:) in conformance TestDerivedCodable
611+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s27preconcurrency_conformances18TestDerivedCodableVSEAASE6encode2toys7Encoder_p_tKFTW
612+
// CHECK-NOT: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF

0 commit comments

Comments
 (0)