Skip to content

Commit 527616d

Browse files
committed
[sema] Move some extra type checking from getIsolationFromAttribute to the attribute checker.
This never belonged in ActorIsolationRequest since it fits perfectly in the attribute checker. This also simplifies the logic before I add code to getIsolationFromAttribute to handle ExecutionAttribute.
1 parent 7cb6581 commit 527616d

File tree

5 files changed

+60
-44
lines changed

5 files changed

+60
-44
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4418,6 +4418,56 @@ void AttributeChecker::visitFrozenAttr(FrozenAttr *attr) {
44184418
}
44194419
}
44204420

4421+
static void checkGlobalActorAttr(
4422+
const Decl *decl,
4423+
std::pair<CustomAttr *, NominalTypeDecl *> &globalActorAttr) {
4424+
auto isolatedAttr = decl->getAttrs().getAttribute<IsolatedAttr>();
4425+
auto nonisolatedAttr = decl->getAttrs().getAttribute<NonisolatedAttr>();
4426+
struct NameAndRange {
4427+
StringRef name;
4428+
SourceRange range;
4429+
4430+
NameAndRange(StringRef _name, SourceRange _range)
4431+
: name(_name), range(_range) {}
4432+
};
4433+
4434+
llvm::SmallVector<NameAndRange, 3> attributes;
4435+
4436+
attributes.push_back(NameAndRange(globalActorAttr.second->getName().str(),
4437+
globalActorAttr.first->getRangeWithAt()));
4438+
4439+
if (isolatedAttr) {
4440+
attributes.push_back(NameAndRange(isolatedAttr->getAttrName(),
4441+
isolatedAttr->getRangeWithAt()));
4442+
}
4443+
if (nonisolatedAttr) {
4444+
attributes.push_back(NameAndRange(nonisolatedAttr->getAttrName(),
4445+
nonisolatedAttr->getRangeWithAt()));
4446+
}
4447+
if (attributes.size() == 1)
4448+
return;
4449+
4450+
if (attributes.size() == 2) {
4451+
decl->diagnose(diag::actor_isolation_multiple_attr_2, decl,
4452+
attributes[0].name, attributes[1].name)
4453+
.highlight(attributes[0].range)
4454+
.highlight(attributes[1].range)
4455+
.warnUntilSwiftVersion(6)
4456+
.fixItRemove(attributes[1].range);
4457+
4458+
} else {
4459+
assert(attributes.size() == 3);
4460+
decl->diagnose(diag::actor_isolation_multiple_attr_3, decl,
4461+
attributes[0].name, attributes[1].name, attributes[2].name)
4462+
.highlight(attributes[0].range)
4463+
.highlight(attributes[1].range)
4464+
.highlight(attributes[2].range)
4465+
.warnUntilSwiftVersion(6)
4466+
.fixItRemove(attributes[1].range)
4467+
.fixItRemove(attributes[2].range);
4468+
}
4469+
}
4470+
44214471
void AttributeChecker::visitCustomAttr(CustomAttr *attr) {
44224472
auto dc = D->getDeclContext();
44234473

@@ -4602,7 +4652,10 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) {
46024652
// retrieval request perform checking for us.
46034653
if (nominal->isGlobalActor()) {
46044654
diagnoseIsolatedDeinitInValueTypes(attr);
4605-
(void)D->getGlobalActorAttr();
4655+
if (auto g = D->getGlobalActorAttr()) {
4656+
checkGlobalActorAttr(D, *g);
4657+
}
4658+
46064659
if (auto value = dyn_cast<ValueDecl>(D)) {
46074660
(void)getActorIsolation(value);
46084661
} else {
@@ -8062,7 +8115,7 @@ class ClosureAttributeChecker
80628115
ctx.evaluator, GlobalActorAttributeRequest{closure}, std::nullopt);
80638116

80648117
if (globalActorAttr && globalActorAttr->first == attr) {
8065-
// if there is an `isolated` parameter, then this global-actor attribute
8118+
// If there is an `isolated` parameter, then this global-actor attribute
80668119
// is invalid.
80678120
for (auto param : *closure->getParameters()) {
80688121
if (param->isIsolated()) {
@@ -8076,6 +8129,8 @@ class ClosureAttributeChecker
80768129
}
80778130
}
80788131

8132+
// Check if we have nonisolated or
8133+
80798134
return; // it's OK
80808135
}
80818136

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4709,46 +4709,6 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
47094709
return std::nullopt;
47104710
}
47114711

4712-
// Only one such attribute is valid, but we only actually care of one of
4713-
// them is a global actor.
4714-
if (numIsolationAttrs > 1 && globalActorAttr && shouldDiagnose) {
4715-
struct NameAndRange {
4716-
StringRef name;
4717-
SourceRange range;
4718-
4719-
NameAndRange(StringRef _name, SourceRange _range)
4720-
: name(_name), range(_range) {}
4721-
};
4722-
4723-
llvm::SmallVector<NameAndRange, 3> attributes;
4724-
if (isolatedAttr) {
4725-
attributes.push_back(NameAndRange(isolatedAttr->getAttrName(),
4726-
isolatedAttr->getRangeWithAt()));
4727-
}
4728-
if (nonisolatedAttr) {
4729-
attributes.push_back(NameAndRange(nonisolatedAttr->getAttrName(),
4730-
nonisolatedAttr->getRangeWithAt()));
4731-
}
4732-
if (globalActorAttr) {
4733-
attributes.push_back(
4734-
NameAndRange(globalActorAttr->second->getName().str(),
4735-
globalActorAttr->first->getRangeWithAt()));
4736-
}
4737-
if (attributes.size() == 3) {
4738-
decl->diagnose(diag::actor_isolation_multiple_attr_3, decl,
4739-
attributes[0].name, attributes[1].name, attributes[2].name)
4740-
.highlight(attributes[0].range)
4741-
.highlight(attributes[1].range)
4742-
.highlight(attributes[2].range);
4743-
} else {
4744-
assert(attributes.size() == 2);
4745-
decl->diagnose(diag::actor_isolation_multiple_attr_2, decl,
4746-
attributes[0].name, attributes[1].name)
4747-
.highlight(attributes[0].range)
4748-
.highlight(attributes[1].range);
4749-
}
4750-
}
4751-
47524712
// If the declaration is explicitly marked 'nonisolated', report it as
47534713
// independent.
47544714
if (nonisolatedAttr) {

test/Concurrency/isolated_parameters.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ func isolatedClosures() {
341341
}
342342
}
343343

344+
// expected-warning@+3 {{global function 'allOfEm' has multiple actor-isolation attributes ('MainActor' and 'nonisolated')}}
344345
// expected-warning@+2 {{global function with 'isolated' parameter cannot be 'nonisolated'; this is an error in the Swift 6 language mode}}{{12-24=}}
345346
// expected-warning@+1 {{global function with 'isolated' parameter cannot have a global actor; this is an error in the Swift 6 language mode}}{{1-12=}}
346347
@MainActor nonisolated func allOfEm(_ a: isolated A) {

test/Concurrency/nonisolated_rules.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class KlassA {
154154

155155
@MainActor
156156
nonisolated struct Conflict {}
157-
// expected-error@-1 {{struct 'Conflict' has multiple actor-isolation attributes ('nonisolated' and 'MainActor')}}
157+
// expected-error@-1 {{struct 'Conflict' has multiple actor-isolation attributes ('MainActor' and 'nonisolated')}}
158158

159159
struct B: Sendable {
160160
// expected-error@+1 {{'nonisolated' can not be applied to variable with non-'Sendable' type 'NonSendable}}

test/attr/global_actor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct Container {
9898
// Redundant attributes
9999
// -----------------------------------------------------------------------
100100
extension SomeActor {
101-
@GA1 nonisolated func conflict1() { } // expected-error 3{{instance method 'conflict1()' has multiple actor-isolation attributes ('nonisolated' and 'GA1')}}
101+
@GA1 nonisolated func conflict1() { } // expected-warning {{instance method 'conflict1()' has multiple actor-isolation attributes ('GA1' and 'nonisolated')}}
102102
}
103103

104104

0 commit comments

Comments
 (0)