@@ -190,7 +190,7 @@ class SILIsolationInfo {
190190 NonisolatedNonsendingTaskIsolated = 0x4 ,
191191
192192 // / The maximum number of bits used by a Flag.
193- MaxNumBits = 2 ,
193+ MaxNumBits = 3 ,
194194 };
195195
196196 using Options = OptionSet<Flag>;
@@ -208,13 +208,19 @@ class SILIsolationInfo {
208208 // / derived isolatedValue from.
209209 ActorInstance actorInstance;
210210
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+
211215 unsigned kind : 8 ;
212216 unsigned options : 8 ;
213217
214218 SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
215- ActorIsolation actorIsolation, Options options = Options())
219+ ActorIsolation actorIsolation, Options options = Options(),
220+ ProtocolDecl *isolatedConformance = nullptr )
216221 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
217- actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
222+ actorInstance (ActorInstance::getForValue(actorInstance)),
223+ isolatedConformance(isolatedConformance), kind(Actor),
218224 options(options.toRaw()) {
219225 assert ((!actorInstance ||
220226 (actorIsolation.getKind () == ActorIsolation::ActorInstance &&
@@ -226,15 +232,20 @@ class SILIsolationInfo {
226232 }
227233
228234 SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
229- ActorIsolation actorIsolation, Options options = Options())
235+ ActorIsolation actorIsolation, Options options = Options(),
236+ ProtocolDecl *isolatedConformance = nullptr)
230237 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
231- actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
238+ actorInstance(actorInstance), isolatedConformance(isolatedConformance),
239+ kind(Actor), options(options.toRaw())
240+ {
232241 assert (actorInstance);
233242 assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
234243 }
235244
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 ) {
238249 }
239250
240251 SILIsolationInfo (Kind kind, Options options = Options())
@@ -261,6 +272,12 @@ class SILIsolationInfo {
261272 return getOptions ().contains (Flag::UnsafeNonIsolated);
262273 }
263274
275+ // Retrieve the protocol to which there is (or could be) an isolated
276+ // conformance.
277+ ProtocolDecl *getIsolatedConformance () const {
278+ return isolatedConformance;
279+ }
280+
264281 SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
265282 assert (*this && " Cannot be unknown" );
266283 auto self = *this ;
@@ -292,6 +309,26 @@ class SILIsolationInfo {
292309 return self;
293310 }
294311
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+
295332 // / Returns true if this actor isolation is derived from an unapplied
296333 // / isolation parameter. When merging, we allow for this to be merged with a
297334 // / more specific isolation kind.
@@ -458,10 +495,13 @@ class SILIsolationInfo {
458495 Flag::UnappliedIsolatedAnyParameter};
459496 }
460497
461- static SILIsolationInfo getGlobalActorIsolated (SILValue value,
462- Type globalActorType) {
498+ static SILIsolationInfo getGlobalActorIsolated (
499+ SILValue value,
500+ Type globalActorType,
501+ ProtocolDecl *isolatedConformance = nullptr ) {
463502 return {value, SILValue () /* no actor instance*/ ,
464- ActorIsolation::forGlobalActor (globalActorType)};
503+ ActorIsolation::forGlobalActor (globalActorType),
504+ Options (), isolatedConformance};
465505 }
466506
467507 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -473,8 +513,9 @@ class SILIsolationInfo {
473513 isolation.getGlobalActor ());
474514 }
475515
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};
478519 }
479520
480521 // / Attempt to infer the isolation region info for \p inst.
0 commit comments