@@ -114,6 +114,10 @@ class ActorInstance {
114
114
}
115
115
};
116
116
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.
117
121
class SILIsolationInfo {
118
122
public:
119
123
// / The lattice is:
@@ -128,6 +132,20 @@ class SILIsolationInfo {
128
132
Actor,
129
133
};
130
134
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
+
131
149
private:
132
150
// / The actor isolation if this value has one. The default unspecified case
133
151
// / otherwise.
@@ -142,13 +160,13 @@ class SILIsolationInfo {
142
160
ActorInstance actorInstance;
143
161
144
162
unsigned kind : 8 ;
145
- unsigned unsafeNonIsolated : 1 ;
163
+ unsigned options : 8 ;
146
164
147
165
SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
148
- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
166
+ ActorIsolation actorIsolation, Options options = Options() )
149
167
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
150
168
actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
151
- unsafeNonIsolated(isUnsafeNonIsolated ) {
169
+ options(options.toRaw() ) {
152
170
assert ((!actorInstance ||
153
171
(actorIsolation.getKind () == ActorIsolation::ActorInstance &&
154
172
actorInstance->getType ()
@@ -159,24 +177,22 @@ class SILIsolationInfo {
159
177
}
160
178
161
179
SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
162
- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
180
+ ActorIsolation actorIsolation, Options options = Options() )
163
181
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
164
- actorInstance(actorInstance), kind(Actor),
165
- unsafeNonIsolated(isUnsafeNonIsolated) {
182
+ actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
166
183
assert (actorInstance);
167
184
assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
168
185
}
169
186
170
187
SILIsolationInfo (Kind kind, SILValue isolatedValue)
171
- : actorIsolation(), isolatedValue(isolatedValue), kind(kind),
172
- unsafeNonIsolated( false ) { }
188
+ : actorIsolation(), isolatedValue(isolatedValue), kind(kind), options( 0 ) {
189
+ }
173
190
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() ) {}
176
193
177
194
public:
178
- SILIsolationInfo ()
179
- : actorIsolation(), kind(Kind::Unknown), unsafeNonIsolated(false ) {}
195
+ SILIsolationInfo () : actorIsolation(), kind(Kind::Unknown), options(0 ) {}
180
196
181
197
operator bool () const { return kind != Kind::Unknown; }
182
198
@@ -188,12 +204,43 @@ class SILIsolationInfo {
188
204
bool isActorIsolated () const { return kind == Kind::Actor; }
189
205
bool isTaskIsolated () const { return kind == Kind::Task; }
190
206
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
+ }
192
214
193
215
SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
194
216
assert (*this && " Cannot be unknown" );
195
217
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
+ }
197
244
return self;
198
245
}
199
246
@@ -243,7 +290,8 @@ class SILIsolationInfo {
243
290
}
244
291
245
292
static SILIsolationInfo getDisconnected (bool isUnsafeNonIsolated) {
246
- return {Kind::Disconnected, isUnsafeNonIsolated};
293
+ return {Kind::Disconnected,
294
+ isUnsafeNonIsolated ? Flag::UnsafeNonIsolated : Flag::None};
247
295
}
248
296
249
297
// / Create an actor isolation for a value that we know is actor isolated to a
@@ -261,7 +309,7 @@ class SILIsolationInfo {
261
309
getFlowSensitiveActorIsolated (SILValue isolatedValue,
262
310
ActorIsolation actorIsolation) {
263
311
return {isolatedValue, SILValue (), actorIsolation,
264
- false /* nonisolated(unsafe) */ };
312
+ Flag::UnappliedIsolatedAnyParameter };
265
313
}
266
314
267
315
// / Only use this as a fallback if we cannot find better information.
@@ -270,8 +318,7 @@ class SILIsolationInfo {
270
318
if (crossing.getCalleeIsolation ().isActorIsolated ()) {
271
319
// SIL level, just let it through
272
320
return SILIsolationInfo (SILValue (), SILValue (),
273
- crossing.getCalleeIsolation (),
274
- false /* nonisolated(unsafe)*/ );
321
+ crossing.getCalleeIsolation ());
275
322
}
276
323
277
324
return {};
@@ -287,8 +334,7 @@ class SILIsolationInfo {
287
334
return {};
288
335
}
289
336
return {isolatedValue, actorInstance,
290
- ActorIsolation::forActorInstanceSelf (typeDecl),
291
- false /* nonisolated(unsafe)*/ };
337
+ ActorIsolation::forActorInstanceSelf (typeDecl)};
292
338
}
293
339
294
340
static SILIsolationInfo getActorInstanceIsolated (SILValue isolatedValue,
@@ -301,8 +347,7 @@ class SILIsolationInfo {
301
347
return {};
302
348
}
303
349
return {isolatedValue, actorInstance,
304
- ActorIsolation::forActorInstanceSelf (typeDecl),
305
- false /* nonisolated(unsafe)*/ };
350
+ ActorIsolation::forActorInstanceSelf (typeDecl)};
306
351
}
307
352
308
353
// / A special actor instance isolated for partial apply cases where we do not
@@ -318,14 +363,13 @@ class SILIsolationInfo {
318
363
}
319
364
return {isolatedValue, SILValue (),
320
365
ActorIsolation::forActorInstanceSelf (typeDecl),
321
- false /* nonisolated(unsafe) */ };
366
+ Flag::UnappliedIsolatedAnyParameter };
322
367
}
323
368
324
369
static SILIsolationInfo getGlobalActorIsolated (SILValue value,
325
370
Type globalActorType) {
326
371
return {value, SILValue () /* no actor instance*/ ,
327
- ActorIsolation::forGlobalActor (globalActorType),
328
- false /* nonisolated(unsafe)*/ };
372
+ ActorIsolation::forGlobalActor (globalActorType)};
329
373
}
330
374
331
375
static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -395,7 +439,7 @@ class SILDynamicMergedIsolationInfo {
395
439
396
440
public:
397
441
SILDynamicMergedIsolationInfo () : innerInfo() {}
398
- explicit SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
442
+ SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
399
443
: innerInfo(innerInfo) {}
400
444
401
445
// / Returns nullptr only if both this isolation info and \p other are actor
0 commit comments