@@ -190,7 +190,7 @@ class SILIsolationInfo {
190
190
NonisolatedNonsendingTaskIsolated = 0x4 ,
191
191
192
192
// / The maximum number of bits used by a Flag.
193
- MaxNumBits = 2 ,
193
+ MaxNumBits = 3 ,
194
194
};
195
195
196
196
using Options = OptionSet<Flag>;
@@ -208,13 +208,19 @@ class SILIsolationInfo {
208
208
// / derived isolatedValue from.
209
209
ActorInstance actorInstance;
210
210
211
+ // / When the isolation is introduced due to a (potentially) isolated
212
+ // / conformance, the protocol whose conformance might be isolated.
213
+ ProtocolDecl *isolatedConformance = nullptr ;
214
+
211
215
unsigned kind : 8 ;
212
216
unsigned options : 8 ;
213
217
214
218
SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
215
- ActorIsolation actorIsolation, Options options = Options())
219
+ ActorIsolation actorIsolation, Options options = Options(),
220
+ ProtocolDecl *isolatedConformance = nullptr )
216
221
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
217
- actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
222
+ actorInstance (ActorInstance::getForValue(actorInstance)),
223
+ isolatedConformance(isolatedConformance), kind(Actor),
218
224
options(options.toRaw()) {
219
225
assert ((!actorInstance ||
220
226
(actorIsolation.getKind () == ActorIsolation::ActorInstance &&
@@ -226,15 +232,20 @@ class SILIsolationInfo {
226
232
}
227
233
228
234
SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
229
- ActorIsolation actorIsolation, Options options = Options())
235
+ ActorIsolation actorIsolation, Options options = Options(),
236
+ ProtocolDecl *isolatedConformance = nullptr)
230
237
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
231
- actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
238
+ actorInstance(actorInstance), isolatedConformance(isolatedConformance),
239
+ kind(Actor), options(options.toRaw())
240
+ {
232
241
assert (actorInstance);
233
242
assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
234
243
}
235
244
236
- SILIsolationInfo (Kind kind, SILValue isolatedValue)
237
- : actorIsolation(), isolatedValue(isolatedValue), kind(kind), options(0 ) {
245
+ SILIsolationInfo (Kind kind, SILValue isolatedValue,
246
+ ProtocolDecl *isolatedConformance = nullptr )
247
+ : actorIsolation(), isolatedValue(isolatedValue),
248
+ isolatedConformance(isolatedConformance), kind(kind), options(0 ) {
238
249
}
239
250
240
251
SILIsolationInfo (Kind kind, Options options = Options())
@@ -261,6 +272,12 @@ class SILIsolationInfo {
261
272
return getOptions ().contains (Flag::UnsafeNonIsolated);
262
273
}
263
274
275
+ // Retrieve the protocol to which there is (or could be) an isolated
276
+ // conformance.
277
+ ProtocolDecl *getIsolatedConformance () const {
278
+ return isolatedConformance;
279
+ }
280
+
264
281
SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
265
282
assert (*this && " Cannot be unknown" );
266
283
auto self = *this ;
@@ -292,6 +309,26 @@ class SILIsolationInfo {
292
309
return self;
293
310
}
294
311
312
+ // / Produce a new isolation info value that merges in the given isolated
313
+ // / conformance value.
314
+ // /
315
+ // / If both isolation infos have an isolation conformance, pick one
316
+ // / arbitrarily. Otherwise, the result has no isolated conformance.
317
+ SILIsolationInfo
318
+ withMergedIsolatedConformance (ProtocolDecl *newIsolatedConformance) const {
319
+ SILIsolationInfo result (*this );
320
+ if (!isolatedConformance || !newIsolatedConformance) {
321
+ result.isolatedConformance = nullptr ;
322
+ return result;
323
+ }
324
+
325
+ result.isolatedConformance =
326
+ ProtocolDecl::compare (isolatedConformance, newIsolatedConformance) <= 0
327
+ ? isolatedConformance
328
+ : newIsolatedConformance;
329
+ return result;
330
+ }
331
+
295
332
// / Returns true if this actor isolation is derived from an unapplied
296
333
// / isolation parameter. When merging, we allow for this to be merged with a
297
334
// / more specific isolation kind.
@@ -458,10 +495,13 @@ class SILIsolationInfo {
458
495
Flag::UnappliedIsolatedAnyParameter};
459
496
}
460
497
461
- static SILIsolationInfo getGlobalActorIsolated (SILValue value,
462
- Type globalActorType) {
498
+ static SILIsolationInfo getGlobalActorIsolated (
499
+ SILValue value,
500
+ Type globalActorType,
501
+ ProtocolDecl *isolatedConformance = nullptr ) {
463
502
return {value, SILValue () /* no actor instance*/ ,
464
- ActorIsolation::forGlobalActor (globalActorType)};
503
+ ActorIsolation::forGlobalActor (globalActorType),
504
+ Options (), isolatedConformance};
465
505
}
466
506
467
507
static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -473,8 +513,9 @@ class SILIsolationInfo {
473
513
isolation.getGlobalActor ());
474
514
}
475
515
476
- static SILIsolationInfo getTaskIsolated (SILValue value) {
477
- return {Kind::Task, value};
516
+ static SILIsolationInfo getTaskIsolated (
517
+ SILValue value, ProtocolDecl *isolatedConformance = nullptr ) {
518
+ return {Kind::Task, value, isolatedConformance};
478
519
}
479
520
480
521
// / Attempt to infer the isolation region info for \p inst.
0 commit comments