@@ -47,6 +47,78 @@ enum class SILFunctionTypeRepresentation : uint8_t;
47
47
48
48
namespace swift {
49
49
50
+ // / The formal isolation of a function type.
51
+ class FunctionTypeIsolation {
52
+ public:
53
+ enum class Kind : uint8_t {
54
+ // / The function is not isolated.
55
+ NonIsolated,
56
+
57
+ // / The function is isolated to a global actor.
58
+ GlobalActor,
59
+
60
+ // / The function has an isolated parameter; which one is indicated in
61
+ // / the parameter list.
62
+ Parameter,
63
+
64
+ // / The function is dynamically isolated.
65
+ Dynamic,
66
+ };
67
+
68
+ static constexpr size_t NumBits = 3 ; // future-proof this slightly
69
+ static constexpr size_t Mask = (1 << NumBits) - 1 ;
70
+
71
+ private:
72
+ llvm::PointerIntPair<Type, NumBits, Kind> value;
73
+
74
+ FunctionTypeIsolation (Kind kind, Type type = Type()) : value(type, kind) {}
75
+
76
+ public:
77
+ static FunctionTypeIsolation forNonIsolated () {
78
+ return { Kind::NonIsolated };
79
+ }
80
+ static FunctionTypeIsolation forGlobalActor (Type type) {
81
+ assert (type && " creating global actor isolation without an actor type" );
82
+ return { Kind::GlobalActor, type };
83
+ }
84
+ static FunctionTypeIsolation forParameter () {
85
+ return { Kind::Parameter };
86
+ }
87
+ static FunctionTypeIsolation forDynamic () {
88
+ return { Kind::Dynamic };
89
+ }
90
+
91
+ Kind getKind () const { return value.getInt (); }
92
+ bool isNonIsolated () const {
93
+ return getKind () == Kind::NonIsolated;
94
+ }
95
+ bool isGlobalActor () const {
96
+ return getKind () == Kind::GlobalActor;
97
+ }
98
+ Type getGlobalActorType () const {
99
+ assert (getKind () == Kind::GlobalActor);
100
+ return value.getPointer ();
101
+ }
102
+ bool isParameter () const {
103
+ return getKind () == Kind::Parameter;
104
+ }
105
+ bool isDynamic () const {
106
+ return getKind () == Kind::Dynamic;
107
+ }
108
+
109
+ // The opaque accessors below are just for the benefit of ExtInfoBuilder,
110
+ // which finds it convenient to break down the type separately. Normal
111
+ // clients should use the accessors above.
112
+
113
+ Type getOpaqueType () const {
114
+ return value.getPointer ();
115
+ }
116
+
117
+ static FunctionTypeIsolation fromOpaqueValues (Kind kind, Type type) {
118
+ return FunctionTypeIsolation (kind, type);
119
+ }
120
+ };
121
+
50
122
// MARK: - ClangTypeInfo
51
123
// / Wrapper class for storing a clang::Type in an (AST|SIL)ExtInfo.
52
124
class ClangTypeInfo {
@@ -373,20 +445,24 @@ class ASTExtInfoBuilder {
373
445
// If bits are added or removed, then TypeBase::NumAFTExtInfoBits
374
446
// and NumMaskBits must be updated, and they must match.
375
447
//
376
- // |representation|noEscape|concurrent|async|throws|differentiability|
377
- // | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 10 |
448
+ // |representation|noEscape|concurrent|async|throws|isolation| differentiability|
449
+ // | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 10 | 11 .. 13 |
378
450
//
379
451
enum : unsigned {
380
452
RepresentationMask = 0xF << 0 ,
381
453
NoEscapeMask = 1 << 4 ,
382
454
SendableMask = 1 << 5 ,
383
455
AsyncMask = 1 << 6 ,
384
456
ThrowsMask = 1 << 7 ,
385
- DifferentiabilityMaskOffset = 8 ,
457
+ IsolationMaskOffset = 8 ,
458
+ IsolationMask = 0x7 << IsolationMaskOffset,
459
+ DifferentiabilityMaskOffset = 11 ,
386
460
DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset,
387
- NumMaskBits = 11
461
+ NumMaskBits = 14
388
462
};
389
463
464
+ static_assert (FunctionTypeIsolation::Mask == 0x7 , " update mask manually" );
465
+
390
466
unsigned bits; // Naturally sized for speed.
391
467
392
468
ClangTypeInfo clangTypeInfo;
@@ -403,33 +479,39 @@ class ASTExtInfoBuilder {
403
479
LifetimeDependenceInfo lifetimeDependenceInfo)
404
480
: bits(bits), clangTypeInfo(clangTypeInfo), globalActor(globalActor),
405
481
thrownError (thrownError),
406
- lifetimeDependenceInfo(lifetimeDependenceInfo) {}
482
+ lifetimeDependenceInfo(lifetimeDependenceInfo) {
483
+ assert (isThrowing () || !thrownError);
484
+ assert (hasGlobalActorFromBits (bits) == !globalActor.isNull ());
485
+ }
407
486
408
487
public:
409
488
// / An ExtInfoBuilder for a typical Swift function: @convention(swift),
410
489
// / @escaping, non-throwing, non-differentiable.
411
490
ASTExtInfoBuilder ()
412
491
: ASTExtInfoBuilder(Representation::Swift, false , false , Type(),
413
492
DifferentiabilityKind::NonDifferentiable, nullptr,
414
- Type(), LifetimeDependenceInfo()) {}
493
+ FunctionTypeIsolation::forNonIsolated(),
494
+ LifetimeDependenceInfo()) {}
415
495
416
496
// Constructor for polymorphic type.
417
497
ASTExtInfoBuilder (Representation rep, bool throws, Type thrownError)
418
498
: ASTExtInfoBuilder(rep, false , throws, thrownError,
419
499
DifferentiabilityKind::NonDifferentiable, nullptr ,
420
- Type (), LifetimeDependenceInfo()) {}
500
+ FunctionTypeIsolation::forNonIsolated (),
501
+ LifetimeDependenceInfo()) {}
421
502
422
503
// Constructor with no defaults.
423
504
ASTExtInfoBuilder (Representation rep, bool isNoEscape, bool throws,
424
505
Type thrownError, DifferentiabilityKind diffKind,
425
- const clang::Type *type, Type globalActor ,
506
+ const clang::Type *type, FunctionTypeIsolation isolation ,
426
507
LifetimeDependenceInfo lifetimeDependenceInfo)
427
508
: ASTExtInfoBuilder(
428
509
((unsigned )rep) | (isNoEscape ? NoEscapeMask : 0 ) |
429
510
(throws ? ThrowsMask : 0 ) |
430
511
(((unsigned )diffKind << DifferentiabilityMaskOffset) &
431
- DifferentiabilityMask),
432
- ClangTypeInfo(type), globalActor, thrownError,
512
+ DifferentiabilityMask) |
513
+ (unsigned (isolation.getKind()) << IsolationMaskOffset),
514
+ ClangTypeInfo(type), isolation.getOpaqueType(), thrownError,
433
515
lifetimeDependenceInfo) {}
434
516
435
517
void checkInvariants () const ;
@@ -474,6 +556,26 @@ class ASTExtInfoBuilder {
474
556
return lifetimeDependenceInfo;
475
557
}
476
558
559
+ FunctionTypeIsolation::Kind getIsolationKind () const {
560
+ return getIsolationKindFromBits (bits);
561
+ }
562
+ static FunctionTypeIsolation::Kind getIsolationKindFromBits (unsigned bits) {
563
+ return FunctionTypeIsolation::Kind (
564
+ (bits & IsolationMask) >> IsolationMaskOffset);
565
+ }
566
+ bool isDynamicallyIsolated () const {
567
+ return getIsolationKind () == FunctionTypeIsolation::Kind::Dynamic;
568
+ }
569
+ static bool hasGlobalActorFromBits (unsigned bits) {
570
+ return getIsolationKindFromBits (bits)
571
+ == FunctionTypeIsolation::Kind::GlobalActor;
572
+ }
573
+
574
+ FunctionTypeIsolation getIsolation () const {
575
+ return FunctionTypeIsolation::fromOpaqueValues (getIsolationKind (),
576
+ globalActor);
577
+ }
578
+
477
579
constexpr bool hasSelfParam () const {
478
580
switch (getSILRepresentation ()) {
479
581
case SILFunctionTypeRepresentation::Thick:
@@ -529,6 +631,7 @@ class ASTExtInfoBuilder {
529
631
}
530
632
[[nodiscard]]
531
633
ASTExtInfoBuilder withThrows (bool throws, Type thrownError) const {
634
+ assert (throws || !thrownError);
532
635
return ASTExtInfoBuilder (
533
636
throws ? (bits | ThrowsMask) : (bits & ~ThrowsMask), clangTypeInfo,
534
637
globalActor, thrownError, lifetimeDependenceInfo);
@@ -566,15 +669,19 @@ class ASTExtInfoBuilder {
566
669
}
567
670
568
671
[[nodiscard]]
569
- ASTExtInfoBuilder withGlobalActor (Type globalActor) const {
672
+ ASTExtInfoBuilder withLifetimeDependenceInfo (
673
+ LifetimeDependenceInfo lifetimeDependenceInfo) const {
570
674
return ASTExtInfoBuilder (bits, clangTypeInfo, globalActor, thrownError,
571
675
lifetimeDependenceInfo);
572
676
}
573
677
574
- [[nodiscard]] ASTExtInfoBuilder withLifetimeDependenceInfo (
575
- LifetimeDependenceInfo lifetimeDependenceInfo) const {
576
- return ASTExtInfoBuilder (bits, clangTypeInfo, globalActor, thrownError,
577
- lifetimeDependenceInfo);
678
+ [[nodiscard]]
679
+ ASTExtInfoBuilder withIsolation (FunctionTypeIsolation isolation) const {
680
+ return ASTExtInfoBuilder (
681
+ (bits & ~IsolationMask)
682
+ | (unsigned (isolation.getKind ()) << IsolationMaskOffset),
683
+ clangTypeInfo, isolation.getOpaqueType (), thrownError,
684
+ lifetimeDependenceInfo);
578
685
}
579
686
580
687
bool isEqualTo (ASTExtInfoBuilder other, bool useClangTypes) const {
@@ -664,6 +771,8 @@ class ASTExtInfo {
664
771
return builder.getLifetimeDependenceInfo ();
665
772
}
666
773
774
+ FunctionTypeIsolation getIsolation () const { return builder.getIsolation (); }
775
+
667
776
// / Helper method for changing the representation.
668
777
// /
669
778
// / Prefer using \c ASTExtInfoBuilder::withRepresentation for chaining.
@@ -712,9 +821,22 @@ class ASTExtInfo {
712
821
return builder.withAsync (async).build ();
713
822
}
714
823
824
+ [[nodiscard]]
825
+ ASTExtInfo withIsolation (FunctionTypeIsolation isolation) const {
826
+ return builder.withIsolation (isolation).build ();
827
+ }
828
+
829
+ [[nodiscard]]
830
+ ASTExtInfo withoutIsolation () const {
831
+ return builder.withIsolation (FunctionTypeIsolation::forNonIsolated ())
832
+ .build ();
833
+ }
834
+
715
835
[[nodiscard]]
716
836
ASTExtInfo withGlobalActor (Type globalActor) const {
717
- return builder.withGlobalActor (globalActor).build ();
837
+ return builder.withIsolation (
838
+ FunctionTypeIsolation::forGlobalActor (globalActor))
839
+ .build ();
718
840
}
719
841
720
842
[[nodiscard]] ASTExtInfo withLifetimeDependenceInfo (
0 commit comments