mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Concurrency] NonisolatedNonsendingByDefault: Extend nonisolated(nonsending) to _openExistential
`_openExistential` is type-checked in a special way which means that we need to explicitly inject `nonisolated(nonsending)` isolation when forming a reference to this builtin.
This commit is contained in:
@@ -2480,20 +2480,36 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
|
||||
CS.getConstraintLocator(locator, ConstraintLocator::ThrownErrorType),
|
||||
0, preparedOverload);
|
||||
FunctionType::Param bodyArgs[] = {FunctionType::Param(openedTy)};
|
||||
|
||||
auto bodyParamIsolation = FunctionTypeIsolation::forNonIsolated();
|
||||
if (CS.getASTContext().LangOpts.hasFeature(
|
||||
Feature::NonisolatedNonsendingByDefault)) {
|
||||
bodyParamIsolation = FunctionTypeIsolation::forNonIsolatedCaller();
|
||||
}
|
||||
|
||||
auto bodyClosure = FunctionType::get(bodyArgs, result,
|
||||
FunctionType::ExtInfoBuilder()
|
||||
.withNoEscape(true)
|
||||
.withThrows(true, thrownError)
|
||||
.withIsolation(bodyParamIsolation)
|
||||
.withAsync(true)
|
||||
.build());
|
||||
FunctionType::Param args[] = {
|
||||
FunctionType::Param(existentialTy),
|
||||
FunctionType::Param(bodyClosure, CS.getASTContext().getIdentifier("do")),
|
||||
};
|
||||
|
||||
auto openExistentialIsolation = FunctionTypeIsolation::forNonIsolated();
|
||||
if (CS.getASTContext().LangOpts.hasFeature(
|
||||
Feature::NonisolatedNonsendingByDefault)) {
|
||||
openExistentialIsolation = FunctionTypeIsolation::forNonIsolatedCaller();
|
||||
}
|
||||
|
||||
auto refType = FunctionType::get(args, result,
|
||||
FunctionType::ExtInfoBuilder()
|
||||
.withNoEscape(false)
|
||||
.withThrows(true, thrownError)
|
||||
.withIsolation(openExistentialIsolation)
|
||||
.withAsync(true)
|
||||
.build());
|
||||
return {refType, refType, refType, refType, Type()};
|
||||
|
||||
@@ -81,6 +81,20 @@ func testClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
protocol P {
|
||||
}
|
||||
|
||||
func open<T: P>(_: T) async {}
|
||||
|
||||
// CHECK-LABEL: sil hidden [ossa] @$s14attr_execution19testOpenExistential11existentialyAA1P_p_tYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @in_guaranteed any P) -> ()
|
||||
// CHECK: bb0([[ISOLATION:%.*]] : @guaranteed $Optional<any Actor>, [[EXISTENTIAL:%.*]] : $*any P):
|
||||
// CHECK: [[OPEN_REF:%.*]] = function_ref @$s14attr_execution4openyyxYaAA1PRzlF
|
||||
// CHECK: apply [[OPEN_REF]]<@opened("{{.*}}", any P) Self>([[ISOLATION]], {{.*}})
|
||||
// CHECK: } // end sil function '$s14attr_execution19testOpenExistential11existentialyAA1P_p_tYaF'
|
||||
func testOpenExistential(existential: any P) async {
|
||||
await _openExistential(existential, do: open)
|
||||
}
|
||||
|
||||
func testWithoutActuallyEscaping(_ f: () async -> ()) async {
|
||||
// CHECK-LABEL: // closure #1 in testWithoutActuallyEscaping(_:)
|
||||
// CHECK-NEXT: // Isolation: caller_isolation_inheriting
|
||||
|
||||
Reference in New Issue
Block a user