[sil] Change SILIsolationInfo inference for classmethods to use SILDeclRef instead of using the AST directly.

We are creating/relying on a contract between the AST and SIL... that SILDeclRef
should accurately describe the method/accessor that a class_method is from. By
doing this we eliminate pattern matching on the AST which ties this code too
tightly to the AST and makes it brittle in the face of AST changes. This also
fixes an issue where we were not handling setters correctly.

I am doing this now since it is natural to fix it along side fixing the
ref_element_addr issue in the previous commit since they are effectively doing
the same thing.

rdar://153207557
This commit is contained in:
Michael Gottesman
2025-10-19 14:00:19 -07:00
parent dfbe7c1e7a
commit 8016bf2332
5 changed files with 808 additions and 97 deletions

View File

@@ -429,6 +429,12 @@ public:
/// Returns true if this SILFunctionArgument is an 'inout sending' parameter.
bool isInOutSending() const;
bool isIsolated() const {
return !isIndirectResult() && !isIndirectErrorResult() &&
getKnownParameterInfo().getOptions().contains(
SILParameterInfo::Isolated);
}
Lifetime getLifetime() const {
return getType()
.getLifetime(*getFunction())

View File

@@ -53,10 +53,16 @@ public:
/// function)... so we just use an artificial ActorInstance to represent
/// self in this case.
CapturedActorSelf = 0x2,
/// An actor instance in an async allocating init where we are going to
/// allocate the actual actor internally. This is considered to be isolated
/// to the actor instance.
ActorAsyncAllocatingInit = 0x3,
};
/// Set to (SILValue(), $KIND) if we have an ActorAccessorInit|CapturedSelf.
/// Is null if we have (SILValue(), Kind::Value).
/// Set to (SILValue(), $KIND) if we have an
/// ActorAccessorInit|CapturedSelf|ActorAsyncAllocatingInit. Is null if we
/// have (SILValue(), Kind::Value).
llvm::PointerIntPair<SILValue, 2> value;
ActorInstance(SILValue value, Kind kind)
@@ -94,6 +100,12 @@ public:
return ActorInstance(SILValue(), Kind::CapturedActorSelf);
}
/// See Kind::ActorAsyncAllocatingInit for explanation on what a
/// ActorAsyncAllocatingInit is.
static ActorInstance getForActorAsyncAllocatingInit() {
return ActorInstance(SILValue(), Kind::ActorAsyncAllocatingInit);
}
explicit operator bool() const { return bool(value.getOpaqueValue()); }
Kind getKind() const { return Kind(value.getInt()); }
@@ -117,6 +129,10 @@ public:
return getKind() == Kind::CapturedActorSelf;
}
bool isActorAsyncAllocatingInit() const {
return getKind() == Kind::ActorAsyncAllocatingInit;
}
bool operator==(const ActorInstance &other) const {
// If both are null, return true.
if (!bool(*this) && !bool(other))
@@ -132,6 +148,7 @@ public:
return getValue() == other.getValue();
case Kind::ActorAccessorInit:
case Kind::CapturedActorSelf:
case Kind::ActorAsyncAllocatingInit:
return true;
}
}

View File

@@ -426,14 +426,17 @@ static bool isPartialApplyNonisolatedUnsafe(PartialApplyInst *pai) {
return foundOneNonIsolatedUnsafe;
}
/// Return the SILIsolationInfo for a class field.
/// Return the SILIsolationInfo for a class field for a ref_element_addr or
/// class_method. Methods that are direct should get their isolation information
/// from the static function rather than from this function.
///
/// \arg queriedValue the actual value that SILIsolationInfo::get was called
/// upon. This is used for IsolationHistory.
///
/// \arg classValue this is the actual underlying class value that we are
/// extracting a field out of. As an example this is the base passed to
/// ref_element_addr or class_method.
/// ref_element_addr or class_method. This /can/ be a metatype potentially in
/// the case of class 'class' methods and computed properties.
///
/// \arg field the actual AST field that we discovered we are querying. This
/// could be the field of the ref_element_addr or an accessor decl extracted
@@ -441,12 +444,13 @@ static bool isPartialApplyNonisolatedUnsafe(PartialApplyInst *pai) {
static SILIsolationInfo computeIsolationForClassField(SILValue queriedValue,
SILValue classValue,
ValueDecl *field) {
// First look for explicit isolation on the field itself. These always
// override what is on the class.
auto varIsolation = swift::getActorIsolation(field);
// If we have a global actor isolated field, then we know that we override
// the actual isolation of the actor or global actor isolated class with
// some other form of isolation. In such a case, we need to use that
// isolation instead.
// If we have an explicitly global actor isolated field, then we must prefer
// that isolation since it takes precedence over any isolation directly on the
// underlying class type.
if (varIsolation.isGlobalActor()) {
assert(!varIsolation.isNonisolatedUnsafe() &&
"Cannot apply both nonisolated(unsafe) and a global actor attribute "
@@ -455,27 +459,74 @@ static SILIsolationInfo computeIsolationForClassField(SILValue queriedValue,
queriedValue, varIsolation.getGlobalActor());
}
// Then check if our field is explicitly nonisolated (not
// nonisolated(unsafe)). In such a case, we want to return disconnected since
// we are overriding the isolation of the actual nominal type. If we have
// nonisolated(unsafe), we want to respect the isolation of the nominal type
// since we just want to squelch the error but still have it be isolated in
// its normal way. This provides more information since we know what the
// underlying isolation /would/ have been.
if (varIsolation.isNonisolated() && !varIsolation.isNonisolatedUnsafe())
return SILIsolationInfo::getDisconnected(false /*nonisolated unsafe*/);
// Ok, we know that we do not have any overriding isolation from the var
// itself... so now we should use isolation from the underlying nominal type.
// First see if we have an actor instance value from an isolated
// SILFunctionArgument.
if (auto instance = ActorInstance::getForValue(classValue)) {
if (auto *fArg = llvm::dyn_cast_or_null<SILFunctionArgument>(
instance.maybeGetValue())) {
if (auto info =
SILIsolationInfo::getActorInstanceIsolated(queriedValue, fArg))
SILIsolationInfo::getActorInstanceIsolated(queriedValue, fArg)) {
return info.withUnsafeNonIsolated(varIsolation.isNonisolatedUnsafe());
}
}
}
auto *nomDecl = classValue->getType().getNominalOrBoundGenericNominal();
// First find out if our classValue is a nominal type and exit early...
if (auto *nomDecl = classValue->getType().getNominalOrBoundGenericNominal()) {
if (auto isolation = swift::getActorIsolation(nomDecl);
isolation && isolation.isGlobalActor()) {
return SILIsolationInfo::getGlobalActorIsolated(
queriedValue, isolation.getGlobalActor())
.withUnsafeNonIsolated(varIsolation.isNonisolatedUnsafe());
}
if (nomDecl->isAnyActor())
return SILIsolationInfo::getActorInstanceIsolated(queriedValue, classValue,
nomDecl)
.withUnsafeNonIsolated(varIsolation.isNonisolatedUnsafe());
if (nomDecl->isAnyActor())
return SILIsolationInfo::getActorInstanceIsolated(queriedValue,
classValue, nomDecl)
.withUnsafeNonIsolated(varIsolation.isNonisolatedUnsafe());
}
if (auto isolation = swift::getActorIsolation(nomDecl);
isolation && isolation.isGlobalActor()) {
return SILIsolationInfo::getGlobalActorIsolated(queriedValue,
isolation.getGlobalActor())
.withUnsafeNonIsolated(varIsolation.isNonisolatedUnsafe());
// If we have a metatype...
if (classValue->getType().isMetatype()) {
// And we can a class nominal decl...
if (auto *nomDecl =
classValue->getType()
.getLoweredInstanceTypeOfMetatype(classValue->getFunction())
.getNominalOrBoundGenericNominal()) {
// See if the nominal decl is global actor isolated. In such a case, we
// know that the metatype is also actor isolated.
if (auto isolation = swift::getActorIsolation(nomDecl);
isolation && isolation.isGlobalActor()) {
return SILIsolationInfo::getGlobalActorIsolated(
queriedValue, isolation.getGlobalActor())
.withUnsafeNonIsolated(varIsolation.isNonisolatedUnsafe());
}
// Then finally check if we have an actor instance and we are getting an
// async allocating initializer for it.
if (nomDecl->isAnyActor()) {
if (auto *constructorDecl = dyn_cast<ConstructorDecl>(field);
constructorDecl && constructorDecl->isAsync()) {
return SILIsolationInfo::getActorInstanceIsolated(
classValue, ActorInstance::getForActorAsyncAllocatingInit(),
nomDecl);
}
}
}
}
return SILIsolationInfo::getDisconnected(varIsolation.isNonisolatedUnsafe());
@@ -759,81 +810,19 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
}
if (auto *cmi = dyn_cast<ClassMethodInst>(inst)) {
// Ok, we know that we do not have an actor... but we might have a global
// actor isolated method. Use the AST to compute the actor isolation and
// check if we are self. If we are not self, we want this to be
// disconnected.
if (auto *expr = cmi->getLoc().getAsASTNode<Expr>()) {
DeclRefExprAnalysis exprAnalysis;
if (exprAnalysis.compute(expr)) {
auto *dre = exprAnalysis.getResult();
auto base = cmi->getOperand();
auto member = cmi->getMember();
// First see if we can get any information from the actual var decl of
// the class_method. We could find isolation or if our value is marked
// as nonisolated(unsafe), we could find that as well. If we have
// nonisolated(unsafe), we just propagate the value. Otherwise, we
// return the isolation.
bool isNonIsolatedUnsafe = exprAnalysis.hasNonisolatedUnsafe();
{
auto isolation = swift::getActorIsolation(dre->getDecl());
if (isolation.isActorIsolated()) {
// Check if we have a global actor and handle it appropriately.
if (isolation.getKind() == ActorIsolation::GlobalActor) {
bool localNonIsolatedUnsafe =
isNonIsolatedUnsafe | isolation.isNonisolatedUnsafe();
return SILIsolationInfo::getGlobalActorIsolated(
cmi, isolation.getGlobalActor())
.withUnsafeNonIsolated(localNonIsolatedUnsafe);
}
// In this case, we have an actor instance that is self.
if (isolation.getKind() != ActorIsolation::ActorInstance &&
isolation.isActorInstanceForSelfParameter()) {
bool localNonIsolatedUnsafe =
isNonIsolatedUnsafe | isolation.isNonisolatedUnsafe();
return SILIsolationInfo::getActorInstanceIsolated(
cmi, cmi->getOperand(),
cmi->getOperand()
->getType()
.getNominalOrBoundGenericNominal())
.withUnsafeNonIsolated(localNonIsolatedUnsafe);
}
}
}
if (auto type = dre->getType()->getNominalOrBoundGenericNominal()) {
if (auto isolation = swift::getActorIsolation(type)) {
if (isolation.isActorIsolated()) {
// Check if we have a global actor and handle it appropriately.
if (isolation.getKind() == ActorIsolation::GlobalActor) {
bool localNonIsolatedUnsafe =
isNonIsolatedUnsafe | isolation.isNonisolatedUnsafe();
return SILIsolationInfo::getGlobalActorIsolated(
cmi, isolation.getGlobalActor())
.withUnsafeNonIsolated(localNonIsolatedUnsafe);
}
// In this case, we have an actor instance that is self.
if (isolation.getKind() != ActorIsolation::ActorInstance &&
isolation.isActorInstanceForSelfParameter()) {
bool localNonIsolatedUnsafe =
isNonIsolatedUnsafe | isolation.isNonisolatedUnsafe();
return SILIsolationInfo::getActorInstanceIsolated(
cmi, cmi->getOperand(),
cmi->getOperand()
->getType()
.getNominalOrBoundGenericNominal())
.withUnsafeNonIsolated(localNonIsolatedUnsafe);
}
}
}
}
if (isNonIsolatedUnsafe)
return SILIsolationInfo::getDisconnected(isNonIsolatedUnsafe);
}
// First see if we can use our SILDeclRef to infer isolation.
if (auto *accessor = member.getAccessorDecl()) {
return computeIsolationForClassField(cmi, base, accessor);
}
if (auto *funcDecl = member.getAbstractFunctionDecl()) {
return computeIsolationForClassField(cmi, base, funcDecl);
}
llvm_unreachable("Unsupported?!");
}
// See if we have a struct_extract from a global-actor-isolated type.
@@ -1392,6 +1381,12 @@ void SILIsolationInfo::print(SILFunction *fn, llvm::raw_ostream &os) const {
os << '\n';
os << "instance: captured actor instance self\n";
return;
case ActorInstance::Kind::ActorAsyncAllocatingInit:
os << "'self'-isolated";
printOptions(os);
os << '\n';
os << "instance: actor async allocating init\n";
return;
}
}
@@ -1522,9 +1517,8 @@ void SILIsolationInfo::printForDiagnostics(SILFunction *fn,
break;
}
case ActorInstance::Kind::ActorAccessorInit:
os << "'self'-isolated";
return;
case ActorInstance::Kind::CapturedActorSelf:
case ActorInstance::Kind::ActorAsyncAllocatingInit:
os << "'self'-isolated";
return;
}
@@ -1591,9 +1585,8 @@ void SILIsolationInfo::printForCodeDiagnostic(SILFunction *fn,
break;
}
case ActorInstance::Kind::ActorAccessorInit:
os << "'self'-isolated code";
return;
case ActorInstance::Kind::CapturedActorSelf:
case ActorInstance::Kind::ActorAsyncAllocatingInit:
os << "'self'-isolated code";
return;
}
@@ -1645,6 +1638,10 @@ void SILIsolationInfo::printForOneLineLogging(SILFunction *fn,
os << "'self'-isolated (captured-actor-self)";
printOptions(os);
return;
case ActorInstance::Kind::ActorAsyncAllocatingInit:
os << "'self'-isolated (actor-async-allocating-init)";
printOptions(os);
return;
}
}
@@ -1876,6 +1873,9 @@ void ActorInstance::print(llvm::raw_ostream &os) const {
case Kind::CapturedActorSelf:
os << "CapturedActorSelf.";
break;
case Kind::ActorAsyncAllocatingInit:
os << "ActorAsyncAllocatingInit.";
break;
}
if (auto value = maybeGetValue()) {

View File

@@ -22,10 +22,22 @@ class NonSendableKlass {
}
actor MyActor {
init()
@MainActor init(_ x: NonSendableKlass)
init() async
var ns: NonSendableKlass
@MainActor var globalActorNS: NonSendableKlass
nonisolated(unsafe) var nsNonisolatedUnsafe: NonSendableKlass
var nsComputed: NonSendableKlass { get set }
@MainActor var globalActorNSComputed: NonSendableKlass { get set }
nonisolated var nsNonisolatedComputed: NonSendableKlass { get set }
func getNS() -> NonSendableKlass
@MainActor func getNSGlobalActor() -> NonSendableKlass
nonisolated func getNSNonisolated() -> NonSendableKlass
func doSomething() async -> NonSendableKlass
}
@@ -40,12 +52,46 @@ struct CustomActor {
var ns: NonSendableKlass
@CustomActor var globalActorNS: NonSendableKlass
nonisolated(unsafe) var nsNonisolatedUnsafe: NonSendableKlass
var nsComputed: NonSendableKlass { get }
@CustomActor var globalActorNSComputed: NonSendableKlass { get set }
nonisolated var nsNonisolatedComputed: NonSendableKlass { get set }
func getNS() -> NonSendableKlass
@CustomActor func getNSGlobalActor() -> NonSendableKlass
nonisolated func getNSNonisolated() -> NonSendableKlass
class var nsClassComputed: NonSendableKlass { get set }
@CustomActor class var globalActorNSClassComputed: NonSendableKlass { get set }
nonisolated(unsafe) class var nsNonisolatedUnsafeClassComputed: NonSendableKlass { get set }
nonisolated class var nsNonisolatedClassComputed: NonSendableKlass { get set }
class func getNSClassFunc() -> NonSendableKlass
@CustomActor class func getNSGlobalActorClassFunc() -> NonSendableKlass
nonisolated class func getNSNonisolatedClassFunc() -> NonSendableKlass
}
class NonisolatedKlass {
var ns: NonSendableKlass
@CustomActor var globalActorNS: NonSendableKlass
nonisolated(unsafe) var nsNonisolatedUnsafe: NonSendableKlass
var nsComputed: NonSendableKlass { get set }
@CustomActor var globalActorNSComputed: NonSendableKlass { get set }
nonisolated var nsNonisolatedComputed: NonSendableKlass { get set }
func getNS() -> NonSendableKlass
@CustomActor func getNSGlobalActor() -> NonSendableKlass
nonisolated func getNSNonisolated() -> NonSendableKlass
class var nsClassComputed: NonSendableKlass { get set }
@CustomActor class var globalActorNSClassComputed: NonSendableKlass { get set }
nonisolated(unsafe) class var nsNonisolatedUnsafeClassComputed: NonSendableKlass { get set }
nonisolated class var nsNonisolatedClassComputed: NonSendableKlass { get set }
class func getNSClassFunc() -> NonSendableKlass
@CustomActor class func getNSGlobalActorClassFunc() -> NonSendableKlass
nonisolated class func getNSNonisolatedClassFunc() -> NonSendableKlass
}
@MainActor struct MainActorIsolatedStruct {
@@ -1226,3 +1272,629 @@ bb0(%0 : $*NonisolatedStruct):
%9999 = tuple ()
return %9999 : $()
}
///////////////////////////////
// MARK: Computed Properties //
///////////////////////////////
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_actor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MyActor, #MyActor.nsComputed!getter : (isolated MyActor) -> () -> NonSendableKlass, $@convention(method) (@sil_isolated @guaranteed MyActor) -> @owned NonSendableKlass
// CHECK: Isolation: 'self'-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_actor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_actor : $@convention(thin) (@guaranteed @sil_isolated MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MyActor, let, name "self"
%1 = class_method %0 : $MyActor, #MyActor.nsComputed!getter : (isolated MyActor) -> () -> NonSendableKlass, $@convention(method) (@sil_isolated @guaranteed MyActor) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_actor_globalactor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MyActor, #MyActor.globalActorNSComputed!getter : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_actor_globalactor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_actor_globalactor : $@convention(thin) (@guaranteed MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MyActor, let, name "self"
%1 = class_method %0, #MyActor.globalActorNSComputed!getter : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_actor_nonisolated: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MyActor, #MyActor.nsNonisolatedComputed!getter : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_actor_nonisolated: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_actor_nonisolated : $@convention(thin) (@sil_isolated @guaranteed MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MyActor, let, name "self"
%1 = class_method %0 : $MyActor, #MyActor.nsNonisolatedComputed!getter : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_globalactorklass: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.nsComputed!getter : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_globalactorklass: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_globalactorklass : $@convention(thin) (@guaranteed MainActorIsolatedKlass) -> () {
bb0(%0 : @guaranteed $MainActorIsolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MainActorIsolatedKlass, let, name "self"
%1 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.nsComputed!getter : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_globalactorklass_globalactor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.globalActorNSComputed!getter : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_globalactorklass_globalactor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_globalactorklass_globalactor : $@convention(thin) (@guaranteed MainActorIsolatedKlass) -> () {
bb0(%0 : @guaranteed $MainActorIsolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MainActorIsolatedKlass, let, name "self"
%1 = class_method %0, #MainActorIsolatedKlass.globalActorNSComputed!getter : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_globalactorklass_nonisolated: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.nsNonisolatedComputed!getter : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_globalactorklass_nonisolated: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_globalactorklass_nonisolated : $@convention(thin) (@guaranteed MainActorIsolatedKlass) -> () {
bb0(%0 : @guaranteed $MainActorIsolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MainActorIsolatedKlass, let, name "self"
%1 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.nsNonisolatedComputed!getter : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.nsComputed!getter : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass : $@convention(thin) (@guaranteed NonisolatedKlass) -> () {
bb0(%0 : @guaranteed $NonisolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $NonisolatedKlass, let, name "self"
%1 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.nsComputed!getter : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass_globalactor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.globalActorNSComputed!getter : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass_globalactor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass_globalactor : $@convention(thin) (@guaranteed NonisolatedKlass) -> () {
bb0(%0 : @guaranteed $NonisolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $NonisolatedKlass, let, name "self"
%1 = class_method %0, #NonisolatedKlass.globalActorNSComputed!getter : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass_nonisolated: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.nsNonisolatedComputed!getter : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass_nonisolated: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_computedproperty_nonisolatedklass_nonisolated : $@convention(thin) (@guaranteed NonisolatedKlass) -> () {
bb0(%0 : @guaranteed $NonisolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $NonisolatedKlass, let, name "self"
%1 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.nsNonisolatedComputed!getter : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
//////////////////////////////////
// MARK: class method functions //
//////////////////////////////////
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_actor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MyActor, #MyActor.getNS : (isolated MyActor) -> () -> NonSendableKlass, $@convention(method) (@sil_isolated @guaranteed MyActor) -> @owned NonSendableKlass
// CHECK: Isolation: 'self'-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_actor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_actor : $@convention(thin) (@guaranteed @sil_isolated MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MyActor, let, name "self"
%1 = class_method %0 : $MyActor, #MyActor.getNS : (isolated MyActor) -> () -> NonSendableKlass, $@convention(method) (@sil_isolated @guaranteed MyActor) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_actor_globalactor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MyActor, #MyActor.getNSGlobalActor : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_actor_globalactor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_actor_globalactor : $@convention(thin) (@guaranteed MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MyActor, let, name "self"
%1 = class_method %0, #MyActor.getNSGlobalActor : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_actor_nonisolated: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MyActor, #MyActor.getNSNonisolated : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_actor_nonisolated: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_actor_nonisolated : $@convention(thin) (@sil_isolated @guaranteed MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MyActor, let, name "self"
%1 = class_method %0 : $MyActor, #MyActor.getNSNonisolated : (MyActor) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MyActor) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_globalactorklass: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.getNS : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_globalactorklass: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_globalactorklass : $@convention(thin) (@guaranteed MainActorIsolatedKlass) -> () {
bb0(%0 : @guaranteed $MainActorIsolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MainActorIsolatedKlass, let, name "self"
%1 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.getNS : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_globalactorklass_globalactor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.getNSGlobalActor : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_globalactorklass_globalactor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_globalactorklass_globalactor : $@convention(thin) (@guaranteed MainActorIsolatedKlass) -> () {
bb0(%0 : @guaranteed $MainActorIsolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MainActorIsolatedKlass, let, name "self"
%1 = class_method %0, #MainActorIsolatedKlass.getNSGlobalActor : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_globalactorklass_nonisolated: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.getNSNonisolated : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_globalactorklass_nonisolated: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_globalactorklass_nonisolated : $@convention(thin) (@guaranteed MainActorIsolatedKlass) -> () {
bb0(%0 : @guaranteed $MainActorIsolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $MainActorIsolatedKlass, let, name "self"
%1 = class_method %0 : $MainActorIsolatedKlass, #MainActorIsolatedKlass.getNSNonisolated : (MainActorIsolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed MainActorIsolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_nonisolatedklass: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.getNS : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_nonisolatedklass: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_nonisolatedklass : $@convention(thin) (@guaranteed NonisolatedKlass) -> () {
bb0(%0 : @guaranteed $NonisolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $NonisolatedKlass, let, name "self"
%1 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.getNS : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_nonisolatedklass_globalactor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.getNSGlobalActor : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_nonisolatedklass_globalactor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_nonisolatedklass_globalactor : $@convention(thin) (@guaranteed NonisolatedKlass) -> () {
bb0(%0 : @guaranteed $NonisolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $NonisolatedKlass, let, name "self"
%1 = class_method %0, #NonisolatedKlass.getNSGlobalActor : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_method_nonisolatedklass_nonisolated: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %2 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.getNSNonisolated : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_method_nonisolatedklass_nonisolated: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_method_nonisolatedklass_nonisolated : $@convention(thin) (@guaranteed NonisolatedKlass) -> () {
bb0(%0 : @guaranteed $NonisolatedKlass):
specify_test "sil_isolation_info_inference @trace[0]"
debug_value %0 : $NonisolatedKlass, let, name "self"
%1 = class_method %0 : $NonisolatedKlass, #NonisolatedKlass.getNSNonisolated : (NonisolatedKlass) -> () -> NonSendableKlass, $@convention(method) (@guaranteed NonisolatedKlass) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
//////////////////////////////
// MARK: metatype allocator //
//////////////////////////////
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_metatype_actor: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MyActor.Type, #MyActor.init!allocator : (MyActor.Type) -> () -> MyActor, $@convention(method) (@thick MyActor.Type) -> @owned MyActor
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_metatype_actor: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_metatype_actor : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MyActor.Type
%1 = class_method %0, #MyActor.init!allocator : (MyActor.Type) -> () -> MyActor, $@convention(method) (@thick MyActor.Type) -> @owned MyActor
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_metatype_actor_global: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MyActor.Type, #MyActor.init!allocator : (MyActor.Type) -> (NonSendableKlass) -> MyActor, $@convention(method) (@owned NonSendableKlass, @thick MyActor.Type) -> @owned MyActor
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_metatype_actor_global: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_metatype_actor_global : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MyActor.Type
%1 = class_method %0, #MyActor.init!allocator : (MyActor.Type) -> (NonSendableKlass) -> MyActor, $@convention(method) (@owned NonSendableKlass, @thick MyActor.Type) -> @owned MyActor
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on test_globalactor_inference_on_nominal_metatype_actor_global_2: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MyActor.Type, #MyActor.init!allocator : (MyActor.Type) -> () async -> MyActor, $@convention(method) @async (@thick MyActor.Type) -> @owned MyActor
// CHECK: Isolation: 'self'-isolated (actor-async-allocating-init)
// CHECK: end running test 1 of 1 on test_globalactor_inference_on_nominal_metatype_actor_global_2: sil_isolation_info_inference with: @trace[0]
sil [ossa] @test_globalactor_inference_on_nominal_metatype_actor_global_2 : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MyActor.Type
%1 = class_method %0, #MyActor.init!allocator : (MyActor.Type) -> () async -> MyActor, $@convention(method) @async (@thick MyActor.Type) -> @owned MyActor
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
//////////////////////////////////////
// MARK: dynamic 'class' properties //
//////////////////////////////////////
//
// DISCUSSION: This is for methods on a class called a 'class method', that is
// methods that are dynamic methods on the metatype. These can only appear on
// classes, not on actors.
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_classproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.nsClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on globalactor_isolated_class_classproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_classproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.nsClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_classproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.nsClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on globalactor_isolated_class_classproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_classproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.nsClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_globalactorclassproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.globalActorNSClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on globalactor_isolated_class_globalactorclassproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_globalactorclassproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.globalActorNSClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_globalactorclassproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.globalActorNSClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on globalactor_isolated_class_globalactorclassproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_globalactorclassproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.globalActorNSClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_nonisolatedunsafeclassproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.nsNonisolatedUnsafeClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated: nonisolated(unsafe)
// CHECK: end running test 1 of 1 on globalactor_isolated_class_nonisolatedunsafeclassproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_nonisolatedunsafeclassproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.nsNonisolatedUnsafeClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_nonisolatedunsafeclassproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.nsNonisolatedUnsafeClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
// CHECK: Isolation: main actor-isolated: nonisolated(unsafe)
// CHECK: end running test 1 of 1 on globalactor_isolated_class_nonisolatedunsafeclassproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_nonisolatedunsafeclassproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.nsNonisolatedUnsafeClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_nonisolatedclassproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.nsNonisolatedClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on globalactor_isolated_class_nonisolatedclassproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_nonisolatedclassproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.nsNonisolatedClassComputed!getter : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_nonisolatedclassproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.nsNonisolatedClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on globalactor_isolated_class_nonisolatedclassproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_nonisolatedclassproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.nsNonisolatedClassComputed!setter : (MainActorIsolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick MainActorIsolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_classproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.nsClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on nonisolated_class_classproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_classproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.nsClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_classproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.nsClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on nonisolated_class_classproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_classproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.nsClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_globalactorclassproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.globalActorNSClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on nonisolated_class_globalactorclassproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_globalactorclassproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.globalActorNSClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_globalactorclassproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.globalActorNSClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on nonisolated_class_globalactorclassproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_globalactorclassproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.globalActorNSClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_nonisolatedunsafeclassproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.nsNonisolatedUnsafeClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected: nonisolated(unsafe)
// CHECK: end running test 1 of 1 on nonisolated_class_nonisolatedunsafeclassproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_nonisolatedunsafeclassproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.nsNonisolatedUnsafeClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_nonisolatedunsafeclassproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.nsNonisolatedUnsafeClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
// CHECK: Isolation: disconnected: nonisolated(unsafe)
// CHECK: end running test 1 of 1 on nonisolated_class_nonisolatedunsafeclassproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_nonisolatedunsafeclassproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.nsNonisolatedUnsafeClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_nonisolatedclassproperty_getter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.nsNonisolatedClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on nonisolated_class_nonisolatedclassproperty_getter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_nonisolatedclassproperty_getter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.nsNonisolatedClassComputed!getter : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_nonisolatedclassproperty_setter: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.nsNonisolatedClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on nonisolated_class_nonisolatedclassproperty_setter: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_nonisolatedclassproperty_setter : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.nsNonisolatedClassComputed!setter : (NonisolatedKlass.Type) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @thick NonisolatedKlass.Type) -> ()
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
///////////////////////////////////
// MARK: Dynamic 'class' methods //
///////////////////////////////////
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_nonisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.getNSClassFunc : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: main actor-isolated
// CHECK: end running test 1 of 1 on globalactor_isolated_class_nonisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_nonisolatedclassmethod : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.getNSClassFunc : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_globalactorisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.getNSGlobalActorClassFunc : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on globalactor_isolated_class_globalactorisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_globalactorisolatedclassmethod : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.getNSGlobalActorClassFunc : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on globalactor_isolated_class_nonisolatedclassmethod_: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick MainActorIsolatedKlass.Type, #MainActorIsolatedKlass.getNSNonisolatedClassFunc : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on globalactor_isolated_class_nonisolatedclassmethod_: sil_isolation_info_inference with: @trace[0]
sil [ossa] @globalactor_isolated_class_nonisolatedclassmethod_ : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick MainActorIsolatedKlass.Type
%1 = class_method %0, #MainActorIsolatedKlass.getNSNonisolatedClassFunc : (MainActorIsolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick MainActorIsolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_nonisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.getNSClassFunc : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on nonisolated_class_nonisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_nonisolatedclassmethod : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.getNSClassFunc : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_globalactorisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.getNSGlobalActorClassFunc : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: global actor 'CustomActor'-isolated
// CHECK: end running test 1 of 1 on nonisolated_class_globalactorisolatedclassmethod: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_globalactorisolatedclassmethod : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.getNSGlobalActorClassFunc : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: begin running test 1 of 1 on nonisolated_class_nonisolatedclassmethod_: sil_isolation_info_inference with: @trace[0]
// CHECK: Input Value: %1 = class_method %0 : $@thick NonisolatedKlass.Type, #NonisolatedKlass.getNSNonisolatedClassFunc : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
// CHECK: Isolation: disconnected
// CHECK: end running test 1 of 1 on nonisolated_class_nonisolatedclassmethod_: sil_isolation_info_inference with: @trace[0]
sil [ossa] @nonisolated_class_nonisolatedclassmethod_ : $@convention(thin) () -> () {
bb0:
specify_test "sil_isolation_info_inference @trace[0]"
%0 = metatype $@thick NonisolatedKlass.Type
%1 = class_method %0, #NonisolatedKlass.getNSNonisolatedClassFunc : (NonisolatedKlass.Type) -> () -> NonSendableKlass, $@convention(method) (@thick NonisolatedKlass.Type) -> @owned NonSendableKlass
debug_value [trace] %1
%9999 = tuple ()
return %9999 : $()
}

View File

@@ -12,7 +12,9 @@
class NonSendableKlass {}
final class SendableKlass : Sendable {}
actor CustomActorInstance {}
actor CustomActorInstance {
func acceptValue(_ x: NonSendableKlass) {}
}
@globalActor
struct CustomActor {
@@ -379,3 +381,17 @@ actor PreferIsolationOfFieldToIsolationOfActor {
}
}
}
// We need to error on this below since ns becomes main actor isolated and then
// we send it into a different actor.
@MainActor
class SetterAssignmentMustInferGlobalIsolationTest {
var nsField = NonSendableKlass()
func send() async {
let ns = NonSendableKlass()
nsField = ns
await CustomActor.shared.acceptValue(ns) // expected-warning {{sending 'ns' risks causing data races}}
// expected-note @-1 {{sending main actor-isolated 'ns' to actor-isolated instance method 'acceptValue' risks causing data races between actor-isolated and main actor-isolated uses}}
}
}