Skip to content

Commit 42108f3

Browse files
committed
[Distributed] allow get only distributed computed properties
1 parent e8c76a1 commit 42108f3

File tree

9 files changed

+307
-64
lines changed

9 files changed

+307
-64
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ SIMPLE_DECL_ATTR(_inheritActorContext, InheritActorContext,
651651
// 117 was 'spawn' and is now unused
652652

653653
CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor,
654-
DeclModifier | OnClass | OnFunc |
654+
DeclModifier | OnClass | OnFunc | OnVar |
655655
DistributedOnly |
656656
ABIBreakingToAdd | ABIBreakingToRemove |
657657
APIBreakingToAdd | APIBreakingToRemove,

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ enum class DescriptiveDeclKind : uint8_t {
144144
Property,
145145
StaticProperty,
146146
ClassProperty,
147+
DistributedProperty,
147148
InfixOperator,
148149
PrefixOperator,
149150
PostfixOperator,
@@ -5240,6 +5241,9 @@ class VarDecl : public AbstractStorageDecl {
52405241
/// Is this an "async let" property?
52415242
bool isAsyncLet() const;
52425243

5244+
/// Does this have a 'distributed' modifier?
5245+
bool isDistributed() const;
5246+
52435247
/// Is this a stored property that will _not_ trigger any user-defined code
52445248
/// upon any kind of access?
52455249
bool isOrdinaryStoredProperty() const;

include/swift/AST/DiagnosticsSema.def

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4493,8 +4493,8 @@ ERROR(actor_isolated_non_self_reference,none,
44934493
"from the main actor|from a non-isolated context}3",
44944494
(DescriptiveDeclKind, DeclName, unsigned, unsigned, Type))
44954495
ERROR(distributed_actor_isolated_non_self_reference,none,
4496-
"distributed actor-isolated %0 %1 can only be referenced inside the "
4497-
"distributed actor",
4496+
"distributed actor-isolated %0 %1 can not be accessed from a "
4497+
"non-isolated context",
44984498
(DescriptiveDeclKind, DeclName))
44994499
ERROR(distributed_actor_needs_explicit_distributed_import,none,
45004500
"'_Distributed' module not imported, required for 'distributed actor'",
@@ -4568,9 +4568,9 @@ ERROR(distributed_actor_isolated_method,none,
45684568
ERROR(distributed_actor_func_param_not_codable,none,
45694569
"parameter '%0' of type %1 in %2 does not conform to '%3'",
45704570
(StringRef, Type, DescriptiveDeclKind, StringRef))
4571-
ERROR(distributed_actor_func_result_not_codable,none,
4572-
"result type %0 of %1 does not conform to '%2'",
4573-
(Type, DescriptiveDeclKind, StringRef))
4571+
ERROR(distributed_actor_target_result_not_codable,none,
4572+
"result type %0 of %1 %2 does not conform to '%3'",
4573+
(Type, DescriptiveDeclKind, Identifier, StringRef))
45744574
ERROR(distributed_actor_remote_func_implemented_manually,none,
45754575
"distributed instance method's %0 remote counterpart %1 cannot not be implemented manually.",
45764576
(Identifier, Identifier))
@@ -4761,9 +4761,19 @@ ERROR(distributed_actor_user_defined_special_property,none,
47614761
"property %0 cannot be defined explicitly, as it conflicts with "
47624762
"distributed actor synthesized stored property",
47634763
(DeclName))
4764+
ERROR(distributed_property_can_only_be_computed_get_only,none,
4765+
"'distributed' computed property %0 can only be have a 'get' implementation",
4766+
(DeclName))
4767+
ERROR(distributed_property_cannot_be_static,none,
4768+
"'distributed' property %0 cannot be 'static'",
4769+
(DeclName))
4770+
ERROR(distributed_property_can_only_be_computed,none,
4771+
"static property %0 cannot be 'distributed', because it is not a computed "
4772+
"get-only property",
4773+
(DeclName))
47644774
NOTE(distributed_actor_isolated_property,none,
4765-
"distributed actor state is only available within the actor instance", // TODO: reword in terms of isolation
4766-
())
4775+
"access to this property is only permitted within the distributed actor %0",
4776+
(DeclName))
47674777

47684778
ERROR(concurrency_lib_missing,none,
47694779
"missing '%0' declaration, probably because the '_Concurrency' "

lib/AST/Decl.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,13 @@ DescriptiveDeclKind Decl::getDescriptiveKind() const {
191191
auto var = cast<VarDecl>(this);
192192
switch (var->getCorrectStaticSpelling()) {
193193
case StaticSpellingKind::None:
194-
if (var->getDeclContext()->isTypeContext())
194+
if (var->getDeclContext()->isTypeContext()) {
195+
if (var->isDistributed() && !var->isLet()) {
196+
return DescriptiveDeclKind::DistributedProperty;
197+
}
198+
195199
return DescriptiveDeclKind::Property;
200+
}
196201
return var->isLet() ? DescriptiveDeclKind::Let
197202
: DescriptiveDeclKind::Var;
198203
case StaticSpellingKind::KeywordStatic:
@@ -299,6 +304,7 @@ StringRef Decl::getDescriptiveKindName(DescriptiveDeclKind K) {
299304
ENTRY(Property, "property");
300305
ENTRY(StaticProperty, "static property");
301306
ENTRY(ClassProperty, "class property");
307+
ENTRY(DistributedProperty, "distributed property");
302308
ENTRY(PrecedenceGroup, "precedence group");
303309
ENTRY(InfixOperator, "infix operator");
304310
ENTRY(PrefixOperator, "prefix operator");
@@ -6304,6 +6310,10 @@ bool VarDecl::isAsyncLet() const {
63046310
return getAttrs().hasAttribute<AsyncAttr>();
63056311
}
63066312

6313+
bool VarDecl::isDistributed() const {
6314+
return getAttrs().hasAttribute<DistributedActorAttr>();
6315+
}
6316+
63076317
bool VarDecl::isOrdinaryStoredProperty() const {
63086318
// we assume if it hasAttachedPropertyWrapper, it has no storage.
63096319
//

lib/Sema/TypeCheckAttr.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5539,9 +5539,14 @@ void AttributeChecker::visitDistributedActorAttr(DistributedActorAttr *attr) {
55395539

55405540
// distributed can be applied to actor definitions and their methods
55415541
if (auto varDecl = dyn_cast<VarDecl>(D)) {
5542-
// distributed can not be applied to stored properties
5543-
diagnoseAndRemoveAttr(attr, diag::distributed_actor_property);
5544-
return;
5542+
if (varDecl->isDistributed()) {
5543+
if (checkDistributedActorProperty(varDecl, /*diagnose=*/true))
5544+
return;
5545+
} else {
5546+
// distributed can not be applied to stored properties
5547+
diagnoseAndRemoveAttr(attr, diag::distributed_actor_property);
5548+
return;
5549+
}
55455550
}
55465551

55475552
// distributed can only be declared on an `actor`

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,16 +1953,17 @@ namespace {
19531953
void noteIsolatedActorMember(ValueDecl *decl, Expr *context) {
19541954
// detect if it is a distributed actor, to provide better isolation notes
19551955

1956-
auto isDistributedActor = false;
1957-
if (auto nominal = decl->getDeclContext()->getSelfNominalTypeDecl())
1958-
isDistributedActor = nominal->isDistributedActor();
1956+
auto nominal = decl->getDeclContext()->getSelfNominalTypeDecl();
1957+
bool isDistributedActor = false;
1958+
if (nominal) isDistributedActor = nominal->isDistributedActor();
19591959

19601960
// FIXME: Make this diagnostic more sensitive to the isolation context of
19611961
// the declaration.
19621962
if (isDistributedActor) {
19631963
if (dyn_cast<VarDecl>(decl)) {
19641964
// Distributed actor properties are never accessible externally.
1965-
decl->diagnose(diag::distributed_actor_isolated_property);
1965+
decl->diagnose(diag::distributed_actor_isolated_property,
1966+
nominal->getName());
19661967
} else {
19671968
// it's a function or subscript
19681969
decl->diagnose(diag::note_distributed_actor_isolated_method,
@@ -4705,9 +4706,9 @@ bool swift::isPotentiallyIsolatedActor(
47054706

47064707
if (var->getName().str().equals("__secretlyKnownToBeLocal")) {
47074708
// FIXME(distributed): we did a dynamic check and know that this actor is
4708-
// local,
4709-
// but we can't express that to the type system; the real implementation
4710-
// will have to mark 'self' as "known to be local" after an is-local check.
4709+
// local, but we can't express that to the type system; the real
4710+
// implementation will have to mark 'self' as "known to be local" after
4711+
// an is-local check.
47114712
return true;
47124713
}
47134714

0 commit comments

Comments
 (0)