Skip to content

[Concurrency] Add a .isolation member on dynamically isolated function values. #72324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 14, 2024

Conversation

hborla
Copy link
Member

@hborla hborla commented Mar 14, 2024

This change implements the .isolation member on function values with dynamically isolated function type. The approach is very straightforward:

  • In the constraint system, member lookup recognizes the name isolation on function types with erased isolation and records a special ExtractFunctionIsolation overload choice.
  • When the ExtractFunctionIsolation overload choice is selected, CSApply injects ExtractFunctionIsolationExpr around the function expression.
  • SILGen then emits the function_extract_isolation instruction.
  • That's it

The .isolation member is equivalent to the extractFunctionIsolation function currently in the concurrency library, but supported on any type of dynamically isolated function; the current API doesn't abstract over effects, ownership, etc.

Once isolated captures are implemented, we can teach the actor isolation checker to recognize when a context is isolated to an actor value that came from ExtractFunctionIsolationExpr and understand that calls to the base function value do not cross an isolation boundary.

@hborla
Copy link
Member Author

hborla commented Mar 14, 2024

@swift-ci please smoke test

@hborla hborla merged commit 0a627bc into swiftlang:main Mar 14, 2024
@hborla hborla deleted the extract-function-isolation-expr branch March 14, 2024 13:56
Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to convert it back into UnresolvedDeclRefExpr if encountered during pre-check?

// member that extracts the isolation value.
if (auto *fn = dyn_cast<FunctionType>(instanceTy)) {
if (fn->getIsolation().isErased() &&
memberName.getBaseIdentifier().str() == "isolation") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think memberName.isSimpleName(Context.Id_isolation) could be used here

@@ -9746,6 +9747,16 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
if (auto *selfTy = instanceTy->getAs<DynamicSelfType>())
instanceTy = selfTy->getSelfType();

// Dynamically isolated function types have a magic '.isolation'
// member that extracts the isolation value.
if (auto *fn = dyn_cast<FunctionType>(instanceTy)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better use instanceTy->getAs<FunctionType>() because member could be wrapped in parens


func extractFunctionIsolationExpr(
_ fn1: @isolated(any) @escaping () async -> Void,
_ fn2: @isolated(any) @escaping (Int, String) -> Bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a few test-cases that deal with optional unwrap (both styles) as well?

angela-laar pushed a commit to angela-laar/swift that referenced this pull request Mar 15, 2024
…tion-expr

[Concurrency] Add a `.isolation` member on dynamically isolated function values.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants