@@ -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,20 @@ 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+
147+ using Options = OptionSet<Flag>;
148+
131149private:
132150 // / The actor isolation if this value has one. The default unspecified case
133151 // / otherwise.
@@ -142,13 +160,13 @@ class SILIsolationInfo {
142160 ActorInstance actorInstance;
143161
144162 unsigned kind : 8 ;
145- unsigned unsafeNonIsolated : 1 ;
163+ unsigned options : 8 ;
146164
147165 SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
148- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
166+ ActorIsolation actorIsolation, Options options = Options() )
149167 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
150168 actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
151- unsafeNonIsolated(isUnsafeNonIsolated ) {
169+ options(options.toRaw() ) {
152170 assert ((!actorInstance ||
153171 (actorIsolation.getKind () == ActorIsolation::ActorInstance &&
154172 actorInstance->getType ()
@@ -159,24 +177,22 @@ class SILIsolationInfo {
159177 }
160178
161179 SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
162- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
180+ ActorIsolation actorIsolation, Options options = Options() )
163181 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
164- actorInstance(actorInstance), kind(Actor),
165- unsafeNonIsolated(isUnsafeNonIsolated) {
182+ actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
166183 assert (actorInstance);
167184 assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
168185 }
169186
170187 SILIsolationInfo (Kind kind, SILValue isolatedValue)
171- : actorIsolation(), isolatedValue(isolatedValue), kind(kind),
172- unsafeNonIsolated( false ) { }
188+ : actorIsolation(), isolatedValue(isolatedValue), kind(kind), options( 0 ) {
189+ }
173190
174- SILIsolationInfo (Kind kind, bool isUnsafeNonIsolated )
175- : actorIsolation(), kind(kind), unsafeNonIsolated(isUnsafeNonIsolated ) {}
191+ SILIsolationInfo (Kind kind, Options options = Options() )
192+ : actorIsolation(), kind(kind), options(options.toRaw() ) {}
176193
177194public:
178- SILIsolationInfo ()
179- : actorIsolation(), kind(Kind::Unknown), unsafeNonIsolated(false ) {}
195+ SILIsolationInfo () : actorIsolation(), kind(Kind::Unknown), options(0 ) {}
180196
181197 operator bool () const { return kind != Kind::Unknown; }
182198
@@ -188,12 +204,43 @@ class SILIsolationInfo {
188204 bool isActorIsolated () const { return kind == Kind::Actor; }
189205 bool isTaskIsolated () const { return kind == Kind::Task; }
190206
191- bool isUnsafeNonIsolated () const { return unsafeNonIsolated; }
207+ Options getOptions () const { return Options (options); }
208+
209+ void setOptions (Options newOptions) { options = newOptions.toRaw (); }
210+
211+ bool isUnsafeNonIsolated () const {
212+ return getOptions ().contains (Flag::UnsafeNonIsolated);
213+ }
192214
193215 SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
194216 assert (*this && " Cannot be unknown" );
195217 auto self = *this ;
196- self.unsafeNonIsolated = newValue;
218+ if (newValue) {
219+ self.options = (self.getOptions () | Flag::UnsafeNonIsolated).toRaw ();
220+ } else {
221+ self.options =
222+ self.getOptions ().toRaw () & ~Options (Flag::UnsafeNonIsolated).toRaw ();
223+ }
224+ return self;
225+ }
226+
227+ // / Returns true if this actor isolation is derived from an unapplied
228+ // / isolation parameter. When merging, we allow for this to be merged with a
229+ // / more specific isolation kind.
230+ bool isUnappliedIsolatedAnyParameter () const {
231+ return getOptions ().contains (Flag::UnappliedIsolatedAnyParameter);
232+ }
233+
234+ SILIsolationInfo withUnappliedIsolatedParameter (bool newValue = true ) const {
235+ assert (*this && " Cannot be unknown" );
236+ auto self = *this ;
237+ if (newValue) {
238+ self.options =
239+ (self.getOptions () | Flag::UnappliedIsolatedAnyParameter).toRaw ();
240+ } else {
241+ self.options = self.getOptions ().toRaw () &
242+ ~Options (Flag::UnappliedIsolatedAnyParameter).toRaw ();
243+ }
197244 return self;
198245 }
199246
@@ -243,7 +290,8 @@ class SILIsolationInfo {
243290 }
244291
245292 static SILIsolationInfo getDisconnected (bool isUnsafeNonIsolated) {
246- return {Kind::Disconnected, isUnsafeNonIsolated};
293+ return {Kind::Disconnected,
294+ isUnsafeNonIsolated ? Flag::UnsafeNonIsolated : Flag::None};
247295 }
248296
249297 // / Create an actor isolation for a value that we know is actor isolated to a
@@ -261,7 +309,7 @@ class SILIsolationInfo {
261309 getFlowSensitiveActorIsolated (SILValue isolatedValue,
262310 ActorIsolation actorIsolation) {
263311 return {isolatedValue, SILValue (), actorIsolation,
264- false /* nonisolated(unsafe) */ };
312+ Flag::UnappliedIsolatedAnyParameter };
265313 }
266314
267315 // / Only use this as a fallback if we cannot find better information.
@@ -270,8 +318,7 @@ class SILIsolationInfo {
270318 if (crossing.getCalleeIsolation ().isActorIsolated ()) {
271319 // SIL level, just let it through
272320 return SILIsolationInfo (SILValue (), SILValue (),
273- crossing.getCalleeIsolation (),
274- false /* nonisolated(unsafe)*/ );
321+ crossing.getCalleeIsolation ());
275322 }
276323
277324 return {};
@@ -287,8 +334,7 @@ class SILIsolationInfo {
287334 return {};
288335 }
289336 return {isolatedValue, actorInstance,
290- ActorIsolation::forActorInstanceSelf (typeDecl),
291- false /* nonisolated(unsafe)*/ };
337+ ActorIsolation::forActorInstanceSelf (typeDecl)};
292338 }
293339
294340 static SILIsolationInfo getActorInstanceIsolated (SILValue isolatedValue,
@@ -301,8 +347,7 @@ class SILIsolationInfo {
301347 return {};
302348 }
303349 return {isolatedValue, actorInstance,
304- ActorIsolation::forActorInstanceSelf (typeDecl),
305- false /* nonisolated(unsafe)*/ };
350+ ActorIsolation::forActorInstanceSelf (typeDecl)};
306351 }
307352
308353 // / A special actor instance isolated for partial apply cases where we do not
@@ -318,14 +363,13 @@ class SILIsolationInfo {
318363 }
319364 return {isolatedValue, SILValue (),
320365 ActorIsolation::forActorInstanceSelf (typeDecl),
321- false /* nonisolated(unsafe) */ };
366+ Flag::UnappliedIsolatedAnyParameter };
322367 }
323368
324369 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
325370 Type globalActorType) {
326371 return {value, SILValue () /* no actor instance*/ ,
327- ActorIsolation::forGlobalActor (globalActorType),
328- false /* nonisolated(unsafe)*/ };
372+ ActorIsolation::forGlobalActor (globalActorType)};
329373 }
330374
331375 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -395,7 +439,7 @@ class SILDynamicMergedIsolationInfo {
395439
396440public:
397441 SILDynamicMergedIsolationInfo () : innerInfo() {}
398- explicit SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
442+ SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
399443 : innerInfo(innerInfo) {}
400444
401445 // / Returns nullptr only if both this isolation info and \p other are actor
0 commit comments