Skip to content

Commit 8c82b6b

Browse files
authored
Merge pull request #67546 from gottesmm/pr-9bcf05ac3fb12f2872cc63507f782c766eba18b7
[sema] Ban user created read/set accessor that produce noncopyable types
2 parents c415744 + 2a1d919 commit 8c82b6b

File tree

6 files changed

+108
-682
lines changed

6 files changed

+108
-682
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7365,6 +7365,9 @@ ERROR(noncopyable_types_cannot_be_resilient, none,
73657365
"non-@frozen public and @usableFromInline noncopyable types are not "
73667366
"supported",
73677367
(const ValueDecl *))
7368+
ERROR(noncopyable_cannot_have_read_set_accessor,none,
7369+
"noncopyable %select{variable|subscript}0 cannot provide a read and set accessor",
7370+
(unsigned))
73687371

73697372
//------------------------------------------------------------------------------
73707373
// MARK: Runtime discoverable attributes (@runtimeMetadata)

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,10 +2479,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
24792479
}
24802480
}
24812481

2482-
// If this is an init accessor property with a default initializer,
2483-
// make sure that it subsumes initializers of all of its "initializes"
2484-
// stored properties.
24852482
if (auto *var = PBD->getSingleVar()) {
2483+
2484+
// If this is an init accessor property with a default initializer,
2485+
// make sure that it subsumes initializers of all of its "initializes"
2486+
// stored properties.
24862487
auto *initAccessor = var->getAccessor(AccessorKind::Init);
24872488
if (initAccessor && PBD->isInitialized(0)) {
24882489
for (auto *property : initAccessor->getInitializedProperties()) {
@@ -2491,6 +2492,26 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
24912492
propertyBinding->setInitializerSubsumed(0);
24922493
}
24932494
}
2495+
2496+
// If we have a pure noncopyable type, we cannot have explicit read/set
2497+
// accessors since this means that we cannot call mutating methods without
2498+
// copying. We do not want to support types that one cannot define a
2499+
// modify operation via a get/set or a modify.
2500+
if (var->getInterfaceType()->isPureMoveOnly()) {
2501+
if (auto *read = var->getAccessor(AccessorKind::Read)) {
2502+
if (!read->isImplicit()) {
2503+
if (auto *set = var->getAccessor(AccessorKind::Set)) {
2504+
if (!set->isImplicit()) {
2505+
var->diagnose(diag::noncopyable_cannot_have_read_set_accessor,
2506+
0);
2507+
PBD->setInvalid();
2508+
var->setInvalid();
2509+
return;
2510+
}
2511+
}
2512+
}
2513+
}
2514+
}
24942515
}
24952516
}
24962517

@@ -2562,6 +2583,23 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
25622583
.fixItReplace(SD->getStaticLoc(), "static");
25632584
}
25642585

2586+
// Reject noncopyable typed subscripts with read/set accessors since we
2587+
// cannot define modify operations upon them without copying the read.
2588+
if (SD->getElementInterfaceType()->isPureMoveOnly()) {
2589+
if (auto *read = SD->getAccessor(AccessorKind::Read)) {
2590+
if (!read->isImplicit()) {
2591+
if (auto *set = SD->getAccessor(AccessorKind::Set)) {
2592+
if (!set->isImplicit()) {
2593+
SD->diagnose(diag::noncopyable_cannot_have_read_set_accessor,
2594+
1);
2595+
SD->setInvalid();
2596+
return;
2597+
}
2598+
}
2599+
}
2600+
}
2601+
}
2602+
25652603
// Now check all the accessors.
25662604
SD->visitEmittedAccessors([&](AccessorDecl *accessor) {
25672605
visit(accessor);

0 commit comments

Comments
 (0)