@@ -114,6 +114,10 @@ class ActorInstance {
114114 }
115115};
116116
117+ // / The isolation info inferred for a specific SILValue. Use
118+ // / SILIsolationInfo::get() to compute these. It is intended to be a
119+ // / conservatively correct model that we expand over time with more pattern
120+ // / matching.
117121class SILIsolationInfo {
118122public:
119123 // / The lattice is:
@@ -128,6 +132,23 @@ class SILIsolationInfo {
128132 Actor,
129133 };
130134
135+ enum class Flag : uint8_t {
136+ None,
137+
138+ // / If set, this means that the element that we derived this from was marked
139+ // / with nonisolated(unsafe).
140+ UnsafeNonIsolated = 0x1 ,
141+
142+ // / If set, this means that this actor isolation is from an isolated
143+ // / parameter and should be allowed to merge into a self parameter.
144+ UnappliedIsolatedAnyParameter = 0x2 ,
145+
146+ // / The maximum number of bits used by a Flag.
147+ MaxNumBits = 2 ,
148+ };
149+
150+ using Options = OptionSet<Flag>;
151+
131152private:
132153 // / The actor isolation if this value has one. The default unspecified case
133154 // / otherwise.
@@ -142,13 +163,13 @@ class SILIsolationInfo {
142163 ActorInstance actorInstance;
143164
144165 unsigned kind : 8 ;
145- unsigned unsafeNonIsolated : 1 ;
166+ unsigned options : 8 ;
146167
147168 SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
148- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
169+ ActorIsolation actorIsolation, Options options = Options() )
149170 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
150171 actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
151- unsafeNonIsolated(isUnsafeNonIsolated ) {
172+ options(options.toRaw() ) {
152173 assert ((!actorInstance ||
153174 (actorIsolation.getKind () == ActorIsolation::ActorInstance &&
154175 actorInstance->getType ()
@@ -159,24 +180,22 @@ class SILIsolationInfo {
159180 }
160181
161182 SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
162- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
183+ ActorIsolation actorIsolation, Options options = Options() )
163184 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
164- actorInstance(actorInstance), kind(Actor),
165- unsafeNonIsolated(isUnsafeNonIsolated) {
185+ actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
166186 assert (actorInstance);
167187 assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
168188 }
169189
170190 SILIsolationInfo (Kind kind, SILValue isolatedValue)
171- : actorIsolation(), isolatedValue(isolatedValue), kind(kind),
172- unsafeNonIsolated( false ) { }
191+ : actorIsolation(), isolatedValue(isolatedValue), kind(kind), options( 0 ) {
192+ }
173193
174- SILIsolationInfo (Kind kind, bool isUnsafeNonIsolated )
175- : actorIsolation(), kind(kind), unsafeNonIsolated(isUnsafeNonIsolated ) {}
194+ SILIsolationInfo (Kind kind, Options options = Options() )
195+ : actorIsolation(), kind(kind), options(options.toRaw() ) {}
176196
177197public:
178- SILIsolationInfo ()
179- : actorIsolation(), kind(Kind::Unknown), unsafeNonIsolated(false ) {}
198+ SILIsolationInfo () : actorIsolation(), kind(Kind::Unknown), options(0 ) {}
180199
181200 operator bool () const { return kind != Kind::Unknown; }
182201
@@ -188,12 +207,43 @@ class SILIsolationInfo {
188207 bool isActorIsolated () const { return kind == Kind::Actor; }
189208 bool isTaskIsolated () const { return kind == Kind::Task; }
190209
191- bool isUnsafeNonIsolated () const { return unsafeNonIsolated; }
210+ Options getOptions () const { return Options (options); }
211+
212+ void setOptions (Options newOptions) { options = newOptions.toRaw (); }
213+
214+ bool isUnsafeNonIsolated () const {
215+ return getOptions ().contains (Flag::UnsafeNonIsolated);
216+ }
192217
193218 SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
194219 assert (*this && " Cannot be unknown" );
195220 auto self = *this ;
196- self.unsafeNonIsolated = newValue;
221+ if (newValue) {
222+ self.options = (self.getOptions () | Flag::UnsafeNonIsolated).toRaw ();
223+ } else {
224+ self.options =
225+ self.getOptions ().toRaw () & ~Options (Flag::UnsafeNonIsolated).toRaw ();
226+ }
227+ return self;
228+ }
229+
230+ // / Returns true if this actor isolation is derived from an unapplied
231+ // / isolation parameter. When merging, we allow for this to be merged with a
232+ // / more specific isolation kind.
233+ bool isUnappliedIsolatedAnyParameter () const {
234+ return getOptions ().contains (Flag::UnappliedIsolatedAnyParameter);
235+ }
236+
237+ SILIsolationInfo withUnappliedIsolatedParameter (bool newValue = true ) const {
238+ assert (*this && " Cannot be unknown" );
239+ auto self = *this ;
240+ if (newValue) {
241+ self.options =
242+ (self.getOptions () | Flag::UnappliedIsolatedAnyParameter).toRaw ();
243+ } else {
244+ self.options = self.getOptions ().toRaw () &
245+ ~Options (Flag::UnappliedIsolatedAnyParameter).toRaw ();
246+ }
197247 return self;
198248 }
199249
@@ -243,7 +293,8 @@ class SILIsolationInfo {
243293 }
244294
245295 static SILIsolationInfo getDisconnected (bool isUnsafeNonIsolated) {
246- return {Kind::Disconnected, isUnsafeNonIsolated};
296+ return {Kind::Disconnected,
297+ isUnsafeNonIsolated ? Flag::UnsafeNonIsolated : Flag::None};
247298 }
248299
249300 // / Create an actor isolation for a value that we know is actor isolated to a
@@ -261,7 +312,7 @@ class SILIsolationInfo {
261312 getFlowSensitiveActorIsolated (SILValue isolatedValue,
262313 ActorIsolation actorIsolation) {
263314 return {isolatedValue, SILValue (), actorIsolation,
264- false /* nonisolated(unsafe) */ };
315+ Flag::UnappliedIsolatedAnyParameter };
265316 }
266317
267318 // / Only use this as a fallback if we cannot find better information.
@@ -270,8 +321,7 @@ class SILIsolationInfo {
270321 if (crossing.getCalleeIsolation ().isActorIsolated ()) {
271322 // SIL level, just let it through
272323 return SILIsolationInfo (SILValue (), SILValue (),
273- crossing.getCalleeIsolation (),
274- false /* nonisolated(unsafe)*/ );
324+ crossing.getCalleeIsolation ());
275325 }
276326
277327 return {};
@@ -287,8 +337,7 @@ class SILIsolationInfo {
287337 return {};
288338 }
289339 return {isolatedValue, actorInstance,
290- ActorIsolation::forActorInstanceSelf (typeDecl),
291- false /* nonisolated(unsafe)*/ };
340+ ActorIsolation::forActorInstanceSelf (typeDecl)};
292341 }
293342
294343 static SILIsolationInfo getActorInstanceIsolated (SILValue isolatedValue,
@@ -301,8 +350,7 @@ class SILIsolationInfo {
301350 return {};
302351 }
303352 return {isolatedValue, actorInstance,
304- ActorIsolation::forActorInstanceSelf (typeDecl),
305- false /* nonisolated(unsafe)*/ };
353+ ActorIsolation::forActorInstanceSelf (typeDecl)};
306354 }
307355
308356 // / A special actor instance isolated for partial apply cases where we do not
@@ -318,14 +366,13 @@ class SILIsolationInfo {
318366 }
319367 return {isolatedValue, SILValue (),
320368 ActorIsolation::forActorInstanceSelf (typeDecl),
321- false /* nonisolated(unsafe) */ };
369+ Flag::UnappliedIsolatedAnyParameter };
322370 }
323371
324372 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
325373 Type globalActorType) {
326374 return {value, SILValue () /* no actor instance*/ ,
327- ActorIsolation::forGlobalActor (globalActorType),
328- false /* nonisolated(unsafe)*/ };
375+ ActorIsolation::forGlobalActor (globalActorType)};
329376 }
330377
331378 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -382,6 +429,9 @@ class SILIsolationInfo {
382429 bool isEqual (const SILIsolationInfo &other) const ;
383430
384431 void Profile (llvm::FoldingSetNodeID &id) const ;
432+
433+ private:
434+ void printOptions (llvm::raw_ostream &os) const ;
385435};
386436
387437// / A SILIsolationInfo that has gone through merging and represents the dynamic
@@ -395,7 +445,7 @@ class SILDynamicMergedIsolationInfo {
395445
396446public:
397447 SILDynamicMergedIsolationInfo () : innerInfo() {}
398- explicit SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
448+ SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
399449 : innerInfo(innerInfo) {}
400450
401451 // / Returns nullptr only if both this isolation info and \p other are actor
@@ -435,6 +485,10 @@ class SILDynamicMergedIsolationInfo {
435485 SWIFT_DEBUG_DUMPER (dumpForDiagnostics()) {
436486 innerInfo.dumpForDiagnostics ();
437487 }
488+
489+ void printForOneLineLogging (llvm::raw_ostream &os) const {
490+ innerInfo.printForOneLineLogging (os);
491+ }
438492};
439493
440494} // namespace swift
0 commit comments