@@ -186,7 +186,7 @@ class SILIsolationInfo {
186186 UnappliedIsolatedAnyParameter = 0x2 ,
187187
188188 // / The maximum number of bits used by a Flag.
189- MaxNumBits = 2 ,
189+ MaxNumBits = 3 ,
190190 };
191191
192192 using Options = OptionSet<Flag>;
@@ -204,13 +204,19 @@ class SILIsolationInfo {
204204 // / derived isolatedValue from.
205205 ActorInstance actorInstance;
206206
207+ // / When the isolation is introduced due to a (potentially) isolated
208+ // / conformance, the protocol whose conformance might be isolated.
209+ ProtocolDecl *isolatedConformance = nullptr ;
210+
207211 unsigned kind : 8 ;
208212 unsigned options : 8 ;
209213
210214 SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
211- ActorIsolation actorIsolation, Options options = Options())
215+ ActorIsolation actorIsolation, Options options = Options(),
216+ ProtocolDecl *isolatedConformance = nullptr )
212217 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
213- actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
218+ actorInstance (ActorInstance::getForValue(actorInstance)),
219+ isolatedConformance(isolatedConformance), kind(Actor),
214220 options(options.toRaw()) {
215221 assert ((!actorInstance ||
216222 (actorIsolation.getKind () == ActorIsolation::ActorInstance &&
@@ -222,15 +228,20 @@ class SILIsolationInfo {
222228 }
223229
224230 SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
225- ActorIsolation actorIsolation, Options options = Options())
231+ ActorIsolation actorIsolation, Options options = Options(),
232+ ProtocolDecl *isolatedConformance = nullptr)
226233 : actorIsolation(actorIsolation), isolatedValue(isolatedValue),
227- actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
234+ actorInstance(actorInstance), isolatedConformance(isolatedConformance),
235+ kind(Actor), options(options.toRaw())
236+ {
228237 assert (actorInstance);
229238 assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
230239 }
231240
232- SILIsolationInfo (Kind kind, SILValue isolatedValue)
233- : actorIsolation(), isolatedValue(isolatedValue), kind(kind), options(0 ) {
241+ SILIsolationInfo (Kind kind, SILValue isolatedValue,
242+ ProtocolDecl *isolatedConformance = nullptr )
243+ : actorIsolation(), isolatedValue(isolatedValue),
244+ isolatedConformance(isolatedConformance), kind(kind), options(0 ) {
234245 }
235246
236247 SILIsolationInfo (Kind kind, Options options = Options())
@@ -257,6 +268,12 @@ class SILIsolationInfo {
257268 return getOptions ().contains (Flag::UnsafeNonIsolated);
258269 }
259270
271+ // Retrieve the protocol to which there is (or could be) an isolated
272+ // conformance.
273+ ProtocolDecl *getIsolatedConformance () const {
274+ return isolatedConformance;
275+ }
276+
260277 SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
261278 assert (*this && " Cannot be unknown" );
262279 auto self = *this ;
@@ -269,6 +286,26 @@ class SILIsolationInfo {
269286 return self;
270287 }
271288
289+ // / Produce a new isolation info value that merges in the given isolated
290+ // / conformance value.
291+ // /
292+ // / If both isolation infos have an isolation conformance, pick one
293+ // / arbitrarily. Otherwise, the result has no isolated conformance.
294+ SILIsolationInfo
295+ withMergedIsolatedConformance (ProtocolDecl *newIsolatedConformance) const {
296+ SILIsolationInfo result (*this );
297+ if (!isolatedConformance || !newIsolatedConformance) {
298+ result.isolatedConformance = nullptr ;
299+ return result;
300+ }
301+
302+ result.isolatedConformance =
303+ ProtocolDecl::compare (isolatedConformance, newIsolatedConformance) <= 0
304+ ? isolatedConformance
305+ : newIsolatedConformance;
306+ return result;
307+ }
308+
272309 // / Returns true if this actor isolation is derived from an unapplied
273310 // / isolation parameter. When merging, we allow for this to be merged with a
274311 // / more specific isolation kind.
@@ -427,10 +464,13 @@ class SILIsolationInfo {
427464 Flag::UnappliedIsolatedAnyParameter};
428465 }
429466
430- static SILIsolationInfo getGlobalActorIsolated (SILValue value,
431- Type globalActorType) {
467+ static SILIsolationInfo getGlobalActorIsolated (
468+ SILValue value,
469+ Type globalActorType,
470+ ProtocolDecl *isolatedConformance = nullptr ) {
432471 return {value, SILValue () /* no actor instance*/ ,
433- ActorIsolation::forGlobalActor (globalActorType)};
472+ ActorIsolation::forGlobalActor (globalActorType),
473+ Options (), isolatedConformance};
434474 }
435475
436476 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -442,8 +482,9 @@ class SILIsolationInfo {
442482 isolation.getGlobalActor ());
443483 }
444484
445- static SILIsolationInfo getTaskIsolated (SILValue value) {
446- return {Kind::Task, value};
485+ static SILIsolationInfo getTaskIsolated (
486+ SILValue value, ProtocolDecl *isolatedConformance = nullptr ) {
487+ return {Kind::Task, value, isolatedConformance};
447488 }
448489
449490 // / Attempt to infer the isolation region info for \p inst.
0 commit comments