@@ -426,6 +426,61 @@ static bool isPartialApplyNonisolatedUnsafe(PartialApplyInst *pai) {
426426 return foundOneNonIsolatedUnsafe;
427427}
428428
429+ // / Return the SILIsolationInfo for a class field.
430+ // /
431+ // / \arg queriedValue the actual value that SILIsolationInfo::get was called
432+ // / upon. This is used for IsolationHistory.
433+ // /
434+ // / \arg classValue this is the actual underlying class value that we are
435+ // / extracting a field out of. As an example this is the base passed to
436+ // / ref_element_addr or class_method.
437+ // /
438+ // / \arg field the actual AST field that we discovered we are querying. This
439+ // / could be the field of the ref_element_addr or an accessor decl extracted
440+ // / from a SILDeclRef of a class_method.
441+ static SILIsolationInfo computeIsolationForClassField (SILValue queriedValue,
442+ SILValue classValue,
443+ ValueDecl *field) {
444+ auto varIsolation = swift::getActorIsolation (field);
445+
446+ // If we have a global actor isolated field, then we know that we override
447+ // the actual isolation of the actor or global actor isolated class with
448+ // some other form of isolation. In such a case, we need to use that
449+ // isolation instead.
450+ if (varIsolation.isGlobalActor ()) {
451+ assert (!varIsolation.isNonisolatedUnsafe () &&
452+ " Cannot apply both nonisolated(unsafe) and a global actor attribute "
453+ " to the same declaration" );
454+ return SILIsolationInfo::getGlobalActorIsolated (
455+ queriedValue, varIsolation.getGlobalActor ());
456+ }
457+
458+ if (auto instance = ActorInstance::getForValue (classValue)) {
459+ if (auto *fArg = llvm::dyn_cast_or_null<SILFunctionArgument>(
460+ instance.maybeGetValue ())) {
461+ if (auto info =
462+ SILIsolationInfo::getActorInstanceIsolated (queriedValue, fArg ))
463+ return info.withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
464+ }
465+ }
466+
467+ auto *nomDecl = classValue->getType ().getNominalOrBoundGenericNominal ();
468+
469+ if (nomDecl->isAnyActor ())
470+ return SILIsolationInfo::getActorInstanceIsolated (queriedValue, classValue,
471+ nomDecl)
472+ .withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
473+
474+ if (auto isolation = swift::getActorIsolation (nomDecl);
475+ isolation && isolation.isGlobalActor ()) {
476+ return SILIsolationInfo::getGlobalActorIsolated (queriedValue,
477+ isolation.getGlobalActor ())
478+ .withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
479+ }
480+
481+ return SILIsolationInfo::getDisconnected (varIsolation.isNonisolatedUnsafe ());
482+ }
483+
429484SILIsolationInfo SILIsolationInfo::get (SILInstruction *inst) {
430485 if (auto fas = FullApplySite::isa (inst)) {
431486 // Before we do anything, see if we have a sending result. In such a case,
@@ -594,48 +649,10 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
594649 return SILIsolationInfo::getDisconnected (partialApplyIsNonIsolatedUnsafe);
595650 }
596651
597- // See if the memory base is a ref_element_addr from an address. If so, add
598- // the actor derived flag.
599- //
600- // This is important so we properly handle setters.
652+ // See if the memory base is a ref_element_addr from an address.
601653 if (auto *rei = dyn_cast<RefElementAddrInst>(inst)) {
602- auto varIsolation = swift::getActorIsolation (rei->getField ());
603-
604- // If we have a global actor isolated field, then we know that we override
605- // the actual isolation of the actor or global actor isolated class with
606- // some other form of isolation. In such a case, we need to use that
607- // isolation instead.
608- if (varIsolation.isGlobalActor ()) {
609- return SILIsolationInfo::getGlobalActorIsolated (
610- rei, varIsolation.getGlobalActor ())
611- .withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
612- }
613-
614- if (auto instance = ActorInstance::getForValue (rei->getOperand ())) {
615- if (auto *fArg = llvm::dyn_cast_or_null<SILFunctionArgument>(
616- instance.maybeGetValue ())) {
617- if (auto info = SILIsolationInfo::getActorInstanceIsolated (rei, fArg ))
618- return info.withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
619- }
620- }
621-
622- auto *nomDecl =
623- rei->getOperand ()->getType ().getNominalOrBoundGenericNominal ();
624-
625- if (nomDecl->isAnyActor ())
626- return SILIsolationInfo::getActorInstanceIsolated (rei, rei->getOperand (),
627- nomDecl)
628- .withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
629-
630- if (auto isolation = swift::getActorIsolation (nomDecl);
631- isolation && isolation.isGlobalActor ()) {
632- return SILIsolationInfo::getGlobalActorIsolated (
633- rei, isolation.getGlobalActor ())
634- .withUnsafeNonIsolated (varIsolation.isNonisolatedUnsafe ());
635- }
636-
637- return SILIsolationInfo::getDisconnected (
638- varIsolation.isNonisolatedUnsafe ());
654+ return computeIsolationForClassField (rei, rei->getOperand (),
655+ rei->getField ());
639656 }
640657
641658 // Check if we have a global_addr inst.
0 commit comments