-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[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
Conversation
c94a2e7
to
16785b1
Compare
@swift-ci Please test |
lib/Sema/TypeCheckStmt.cpp
Outdated
@@ -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); |
There was a problem hiding this comment.
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));
There was a problem hiding this comment.
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()
?
There was a problem hiding this comment.
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.
lib/IDE/Refactoring.cpp
Outdated
@@ -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())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated changes?
There was a problem hiding this comment.
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.
16785b1
to
9fcfbe5
Compare
@swift-ci Please test |
Build failed |
@swift-ci Please test macOS |
9fcfbe5
to
cfe51d2
Compare
@swift-ci Please test |
Build failed |
actor MyActor {} | ||
|
||
@globalActor | ||
class MyGlobalActor { | ||
static var shared = MyActor() | ||
} |
There was a problem hiding this comment.
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 astatic let
property namedshared
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?
There was a problem hiding this comment.
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!
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
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>
}
}
}
cfe51d2
to
c535eb5
Compare
@swift-ci Please test |
Build failed |
|
||
@globalActor | ||
actor MyGlobalActor { | ||
static var shared = MyActor() |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
c535eb5
to
6725e2b
Compare
@swift-ci Please test |
Build failed |
@swift-ci Please test macOS |
Build failed |
@swift-ci Please test macOS |
Build failed |
@swift-ci Please smoke test macOS |
// TypeCheckASTNodeAtLocRequest is called multiple times, as described | ||
// above. | ||
auto ActorIsolation = determineClosureActorIsolation(CE); | ||
CE->setActorIsolation(ActorIsolation); |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
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