Skip to content

[Concurrency] explicit nonisolated specification for closures #72175

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

Conversation

sophiapoirier
Copy link
Contributor

Copy link
Contributor

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

This reminded me about the let nonisolated = ""; Task { nonisolated in } case, did we figure out how to deal with those, like that I guess or we ignore that weird case?

Task {`nonisolated` in }

@sophiapoirier
Copy link
Contributor Author

I believe that is not an issue. Your example already is valid code and, without this change, would declare an inferred-type parameter to the closure nonisolated, so that would be inner scope and not conflict with the outer declaration of a variable named nonisolated. The change does introduce a source break in the case that someone intended to have a closure parameter named nonisolated, which I do address in the proposal.

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

I don’t think this approach works.

For example the following is currently valid Swift code:

let closure = { open in
    print(open)
}
closure("abc")

But with this change I assume that open would get parsed as a decl modifier and it would stop working. It would definitely be good to add a test case for something like this.


Also, this needs implementation in the new parser as well

@sophiapoirier
Copy link
Contributor Author

I don’t think this approach works.

For example the following is currently valid Swift code:

let closure = { open in
    print(open)
}
closure("abc")

But with this change I assume that open would get parsed as a decl modifier and it would stop working. It would definitely be good to add a test case for something like this.

Ah good point. My current implementation will at least fail later any modifier other than nonisolated, however that will increase the potential for source breaking to stop allowing other modifiers or contextual keywords to be used as closure parameter names. I will restore an earlier albeit more complicated implementation that I had been using...

Also, this needs implementation in the new parser as well

Yes sorry, I meant to comment that I am working on that, but due to the nature of the change, the lack of it does not block CI here so I wanted to open this for review earlier rather than wait.

@ahoppen
Copy link
Member

ahoppen commented Mar 8, 2024

FWIW I think that even the source break for nonisolated is a blocker for implementing decl modifiers in closures like this.

@sophiapoirier
Copy link
Contributor Author

FWIW I think that even the source break for nonisolated is a blocker for implementing decl modifiers in closures like this.

No one on the pitch as of yet has expressed concern about this, so you may want to if it worries you: https://forums.swift.org/t/closure-isolation-control/70378

@sophiapoirier sophiapoirier force-pushed the explicitly-nonisolated-closure branch 2 times, most recently from 80d83cd to e564145 Compare March 8, 2024 19:54
@sophiapoirier sophiapoirier requested a review from rjmccall March 8, 2024 19:54
@sophiapoirier sophiapoirier changed the title explicit nonisolated specification for closures [Concurrency] explicit nonisolated specification for closures Mar 8, 2024
@sophiapoirier sophiapoirier force-pushed the explicitly-nonisolated-closure branch from 63170ad to 94969ed Compare March 8, 2024 22:08
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.

Does this flag need to be serialized into AbstractClosureExprLayout as well?

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -dump-ast %s -disable-availability-checking | %FileCheck %s
// RUN: %target-swift-frontend -dump-ast %s -disable-availability-checking -enable-experimental-feature ClosureIsolation | %FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

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

Since you added -enable-experimental-feature this test-case now needs // REQUIRES: asserts

@sophiapoirier
Copy link
Contributor Author

sophiapoirier commented Mar 12, 2024

Does this flag need to be serialized into AbstractClosureExprLayout as well?

I do not believe so. Technically speaking, no flag or new state has been added. Closures already have had formal isolation, just not the ability to explicitly specify the option of nonisolated. Looking at SerializedAbstractClosureExpr, its purpose is described to preserve AST structure. Discussing with @rjmccall , it seems that if there a need arose to know the isolation for a DeclContext, we should serialize the isolation property itself. We do not currently serialize anything from the context.

@xedin
Copy link
Contributor

xedin commented Mar 12, 2024

@sophiapoirier What I meant by "flag" is whether nonisolated is stated on the closure or not. If I understand it correctly, previously isolation was always inferred now it could be explicit, so if the closure is deserialized and something asks for its isolation without the nonisolated bit preserved is there a possibility such a request would produce an incorrect result?

@sophiapoirier
Copy link
Contributor Author

@sophiapoirier What I meant by "flag" is whether nonisolated is stated on the closure or not. If I understand it correctly, previously isolation was always inferred now it could be explicit, so if the closure is deserialized and something asks for its isolation without the nonisolated bit preserved is there a possibility such a request would produce an incorrect result?

Ah I see. I would still go back though to what I said about currently SerializedAbstractClosureExpr and its counterpart AbstractClosureExprLayout serialize nothing about the context and no other attributes, no parameters, no effect specifiers, etc.

@sophiapoirier
Copy link
Contributor Author

Due to bike shedding on syntax, I am holding off on swift-syntax implementation pending language evolution review decisions on a final syntax direction. Currently I have omitted one test that would fail due to different results from swift-syntax, but I will introduce it along with a final syntax implementation.

@sophiapoirier sophiapoirier force-pushed the explicitly-nonisolated-closure branch from 57d7ce0 to d683dd8 Compare March 14, 2024 17:13
@sophiapoirier
Copy link
Contributor Author

squashing resets CI results??? RUDE.

@sophiapoirier sophiapoirier force-pushed the explicitly-nonisolated-closure branch from f60508a to 5ce7be7 Compare March 14, 2024 19:24
@sophiapoirier
Copy link
Contributor Author

@swift-ci please test

@sophiapoirier sophiapoirier merged commit 95abb73 into swiftlang:main Mar 15, 2024
@sophiapoirier sophiapoirier deleted the explicitly-nonisolated-closure branch March 15, 2024 00:17
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.

4 participants