Skip to content

[CodeComplete] Mark results as not recommended if global actor context doesn't match #37711

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 1 commit into from
Jun 23, 2021

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented May 31, 2021

Annotate cross-actor references to global actors as async and mark them as not-recommended if they must be executed on a different actor than the current context is on.

Resolves rdar://75902598

@ahoppen ahoppen requested review from rintaro and DougGregor May 31, 2021 19:06
@ahoppen ahoppen force-pushed the pr/global-actor-completion branch from c94a2e7 to 16785b1 Compare June 15, 2021 09:42
@swiftlang swiftlang deleted a comment from swift-ci Jun 15, 2021
@swiftlang swiftlang deleted a comment from swift-ci Jun 15, 2021
@swiftlang swiftlang deleted a comment from swift-ci Jun 15, 2021
@swiftlang swiftlang deleted a comment from swift-ci Jun 15, 2021
@swiftlang swiftlang deleted a comment from swift-ci Jun 15, 2021
@swiftlang swiftlang deleted a comment from swift-ci Jun 15, 2021
@ahoppen
Copy link
Member Author

ahoppen commented Jun 15, 2021

@swift-ci Please test

@@ -1949,6 +1949,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(Evaluator &evaluator,
if (auto CE = dyn_cast<ClosureExpr>(DC)) {
if (CE->getBodyState() == ClosureExpr::BodyState::Parsed) {
swift::typeCheckASTNodeAtLoc(CE->getParent(), CE->getLoc());
checkClosureActorIsolation(CE);
Copy link
Member

@rintaro rintaro Jun 15, 2021

Choose a reason for hiding this comment

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

I'm concerned that ActorIsolationChecker walk into unrelated sibling closures or the children of the current closure. Since TypeCheckASTNodeAtLocRequest::evaluate is called multiple times in a function from the outer closure to inner closure, in this implementation, the walker walks into the inner closures multiple times.

How do you think about exposing ActorIsolationChecker::determineClosureIsolation() and call it directly?

ActorIsolationChecker checker(closure->getParent());
closure->setActorIsolation(checker->determineClosureIsolation(closure));

Copy link
Member

Choose a reason for hiding this comment

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

Or, how about calling checkFunctionActorIsolation() (or checkTopLevelActorIsolation()) in ide::typeCheckContextAt() right after calling typeCheckASTNodeAtLoc()?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. I didn’t realize that TypeCheckASTNodeAtLocRequest was called multiple times.

I think it’ll be good to just set the current closure’s actor isolation as you proposed in the first comment because it minimizes the amount of actor isolation checking that needs to be done. I’ll update it.

@@ -4571,7 +4571,8 @@ struct CallbackCondition {
/// }
/// ```
CallbackCondition(const Decl *Subject, const CaseLabelItem *CaseItem) {
if (auto *EEP = dyn_cast<EnumElementPattern>(CaseItem->getPattern())) {
if (auto *EEP = dyn_cast<EnumElementPattern>(
CaseItem->getPattern()->getSemanticsProvidingPattern())) {
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated changes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, yes. I’ll remove it.

@ahoppen ahoppen force-pushed the pr/global-actor-completion branch from 16785b1 to 9fcfbe5 Compare June 15, 2021 21:45
@ahoppen
Copy link
Member Author

ahoppen commented Jun 15, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 9fcfbe59965475f3ffde62cf654f2158fceb4200

@ahoppen
Copy link
Member Author

ahoppen commented Jun 16, 2021

@swift-ci Please test macOS

@ahoppen ahoppen force-pushed the pr/global-actor-completion branch from 9fcfbe5 to cfe51d2 Compare June 16, 2021 10:57
@ahoppen
Copy link
Member Author

ahoppen commented Jun 16, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - cfe51d27f873043d8720dddc3dcb7ad05880529c

Comment on lines 7 to 10
actor MyActor {}

@globalActor
class MyGlobalActor {
static var shared = MyActor()
}
Copy link
Member

Choose a reason for hiding this comment

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

Global actor definition has been revised in the proposal

A global actor is an actor type that has the @globalActor attribute and contains a static let property named shared that provides an instance of the actor.

The type of shared must be of the enclosing actor type

@globalActor actor MyGlobalActor {
  static let shared = MyGlobalActor()
}

I know other test files still uses old syntax, but can we use the new syntax here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn’t realize that. Thanks!

}
}
}

Copy link
Member

Choose a reason for hiding this comment

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

Could you add a nested single expression closure test? e.g.

@MyGlobalActor func globalFuncOnMyGlobalActor() {}
@MyOtherGlobalActor func globalFuncOnMyOtherGlobalActor() {}

func foo<T>(_: () async -> T) {}

@MyGlobalActor func test() {
    foo {
        foo {
            <HERE>
        }
    }
}

@ahoppen ahoppen force-pushed the pr/global-actor-completion branch from cfe51d2 to c535eb5 Compare June 17, 2021 07:08
@ahoppen
Copy link
Member Author

ahoppen commented Jun 17, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - c535eb54ca4e282e17430eb54694c77c2181eee7


@globalActor
actor MyGlobalActor {
static var shared = MyActor()
Copy link
Member

Choose a reason for hiding this comment

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

I believe this must be MyGlobalActor in the new syntax.

The type of shared must be of the enclosing actor type

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, I missed that part. Fixed it now.

…t doesn't match

Annotate cross-actor references to global actors as `async` and mark them as not-recommended if they must be executed on a different actor than the current context is on.

Resolves rdar://75902598
@ahoppen ahoppen force-pushed the pr/global-actor-completion branch from c535eb5 to 6725e2b Compare June 17, 2021 21:14
@ahoppen
Copy link
Member Author

ahoppen commented Jun 17, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 6725e2b

@ahoppen
Copy link
Member Author

ahoppen commented Jun 22, 2021

@swift-ci Please test macOS

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 6725e2b

@ahoppen
Copy link
Member Author

ahoppen commented Jun 22, 2021

@swift-ci Please test macOS

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 6725e2b

@ahoppen
Copy link
Member Author

ahoppen commented Jun 23, 2021

@swift-ci Please smoke test macOS

@ahoppen ahoppen merged commit 872ecb0 into swiftlang:main Jun 23, 2021
@ahoppen ahoppen deleted the pr/global-actor-completion branch June 23, 2021 16:49
// TypeCheckASTNodeAtLocRequest is called multiple times, as described
// above.
auto ActorIsolation = determineClosureActorIsolation(CE);
CE->setActorIsolation(ActorIsolation);
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, it feels a bit dicey setting the actor isolation for a closure in more than one place. Should we request'ify determineClosureActorIsolation?

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree that it’s not really pretty. But the problem is that the ActorIsolationChecker currently implicitly assumes that it’s walking the tree top to bottom.

IMHO the proper solution would be to completely requesting ActorIsolationChecker so that it works bottom to top, requesting the actor isolation of an outer type as needed. But I felt that was too big of a change for Swift 5.5 and that’s why I stuck with the current, more local, approach.

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