2020
2121namespace swift {
2222
23+ class TypeExpr ;
24+
2325 // / Flags that describe extra attributes on protocol conformances.
2426enum class ProtocolConformanceFlags {
2527 // / @unchecked conformance
@@ -34,16 +36,107 @@ enum class ProtocolConformanceFlags {
3436 // / @retroactive conformance
3537 Retroactive = 0x08 ,
3638
37- // / @isolated conformance
38- Isolated = 0x10 ,
39+ // / nonisolated, which suppresses and inferred global actor isolation
40+ Nonisolated = 0x10 ,
41+
42+ // / The conformance is global-actor-isolated; the global actor will be
43+ // / stored separately.
44+ GlobalActorIsolated = 0x20 ,
3945
4046 // Note: whenever you add a bit here, update
4147 // NumProtocolConformanceOptions below.
4248};
4349
50+ template <typename TheOptionSet>
51+ struct OptionSetStorageType ;
52+
53+ template <typename Flags, typename StorageType>
54+ struct OptionSetStorageType <OptionSet<Flags, StorageType>> {
55+ using Type = StorageType;
56+ };
57+
4458// / Options that describe extra attributes on protocol conformances.
45- using ProtocolConformanceOptions =
46- OptionSet<ProtocolConformanceFlags>;
59+ class ProtocolConformanceOptions {
60+ // / The set of options.
61+ OptionSet<ProtocolConformanceFlags> options;
62+
63+ // / Global actor isolation for this conformance.
64+ TypeExpr *globalActorIsolationType = nullptr ;
65+
66+ public:
67+ using StorageType =
68+ OptionSetStorageType<OptionSet<ProtocolConformanceFlags>>::Type;
69+
70+ ProtocolConformanceOptions () { }
71+
72+ ProtocolConformanceOptions (ProtocolConformanceFlags flag)
73+ : ProtocolConformanceOptions(static_cast <StorageType>(flag), nullptr ) { }
74+
75+ ProtocolConformanceOptions (StorageType flagBits,
76+ TypeExpr *globalActorIsolationType)
77+ : options(flagBits), globalActorIsolationType(globalActorIsolationType) {
78+ assert (options.contains (ProtocolConformanceFlags::GlobalActorIsolated) ==
79+ (bool )globalActorIsolationType);
80+ }
81+
82+ bool contains (ProtocolConformanceFlags flag) const {
83+ return options.contains (flag);
84+ }
85+
86+ TypeExpr *getGlobalActorIsolationType () const {
87+ return globalActorIsolationType;
88+ }
89+
90+ void setGlobalActorIsolation (TypeExpr *globalActorIsolationType) {
91+ options |= ProtocolConformanceFlags::GlobalActorIsolated;
92+ this ->globalActorIsolationType = globalActorIsolationType;
93+ }
94+
95+ // / Retrieve the raw bits for just the flags part of the options. You also
96+ // / need to get the global actor isolation (separately) to reconstitute the
97+ // / options.
98+ StorageType toRaw () const {
99+ return options.toRaw ();
100+ }
101+
102+ ProtocolConformanceOptions &operator |=(ProtocolConformanceFlags flag) {
103+ assert (flag != ProtocolConformanceFlags::GlobalActorIsolated &&
104+ " global actor isolation requires a type; use setGlobalActorIsolation" );
105+ options |= flag;
106+ return *this ;
107+ }
108+
109+ ProtocolConformanceOptions &
110+ operator |=(const ProtocolConformanceOptions &other) {
111+ options |= other.options ;
112+ if (other.globalActorIsolationType && !globalActorIsolationType)
113+ globalActorIsolationType = other.globalActorIsolationType ;
114+ return *this ;
115+ }
116+
117+ ProtocolConformanceOptions &operator -=(ProtocolConformanceFlags flag) {
118+ options -= flag;
119+ if (flag == ProtocolConformanceFlags::GlobalActorIsolated)
120+ globalActorIsolationType = nullptr ;
121+ return *this ;
122+ }
123+
124+ friend ProtocolConformanceOptions operator |(
125+ const ProtocolConformanceOptions &lhs,
126+ const ProtocolConformanceOptions &rhs) {
127+ ProtocolConformanceOptions result (lhs);
128+ result |= rhs;
129+ return result;
130+ }
131+
132+ friend ProtocolConformanceOptions operator -(
133+ const ProtocolConformanceOptions &lhs,
134+ ProtocolConformanceFlags flag) {
135+ ProtocolConformanceOptions result (lhs);
136+ result -= flag;
137+ return result;
138+ }
139+ };
47140
48141inline ProtocolConformanceOptions operator |(
49142 ProtocolConformanceFlags flag1,
@@ -52,7 +145,7 @@ inline ProtocolConformanceOptions operator|(
52145}
53146
54147enum : unsigned {
55- NumProtocolConformanceOptions = 5
148+ NumProtocolConformanceOptions = 6
56149};
57150
58151} // end namespace swift
0 commit comments