Skip to content

Commit f44d7e5

Browse files
committed
Add diagnostics for ownership modifiers on borrow/mutate accessors
1 parent 6f1936f commit f44d7e5

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,9 +1798,16 @@ ERROR(mutating_invalid_classes,none, "%0 is not valid on %kindonly1s in "
17981798
ERROR(functions_mutating_and_not,none,
17991799
"method must not be declared both %0 and %1",
18001800
(SelfAccessKind, SelfAccessKind))
1801+
18011802
ERROR(static_functions_not_mutating,none,
18021803
"static functions must not be declared mutating", ())
18031804

1805+
ERROR(consuming_invalid_borrow_mutate_accessor, none,
1806+
"%0 cannot be declared consuming", (StringRef))
1807+
1808+
ERROR(ownership_modifier_unsupported_borrow_mutate_accessor, none,
1809+
"%0 ownership modifier is not yet supported on %1", (StringRef, StringRef))
1810+
18041811
ERROR(readwriter_mutatingness_differs_from_reader_or_writer_mutatingness,none,
18051812
"%0 cannot be %1 when "
18061813
"%select{both the %3 is %4 and the %5 is not %6|either the %3 is not %4 or the %5 is %6|the %3 is not %4|the %5 is %6}2",

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7595,7 +7595,7 @@ StringRef swift::getAccessorNameForDiagnostic(AccessorKind accessorKind,
75957595
case AccessorKind::Init:
75967596
return article ? "an init accessor" : "init accessor";
75977597
case AccessorKind::Borrow:
7598-
return article ? " a 'borrow' accessor" : "borrow accessor";
7598+
return article ? "a 'borrow' accessor" : "borrow accessor";
75997599
case AccessorKind::Mutate:
76007600
return article ? "a 'mutate' accessor" : "mutate accessor";
76017601
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,31 @@ void AttributeChecker::visitMutationAttr(DeclAttribute *attr) {
708708
// Verify that we don't have a static function.
709709
if (FD->isStatic())
710710
diagnoseAndRemoveAttr(attr, diag::static_functions_not_mutating);
711+
712+
auto *accessor = dyn_cast<AccessorDecl>(FD);
713+
if (accessor &&
714+
(accessor->isBorrowAccessor() || accessor->isMutateAccessor())) {
715+
if (attrModifier == SelfAccessKind::Consuming ||
716+
attrModifier == SelfAccessKind::LegacyConsuming) {
717+
diagnoseAndRemoveAttr(
718+
attr, diag::consuming_invalid_borrow_mutate_accessor,
719+
getAccessorNameForDiagnostic(accessor, /*article*/ true));
720+
}
721+
if (attrModifier == SelfAccessKind::NonMutating &&
722+
accessor->isMutateAccessor()) {
723+
diagnoseAndRemoveAttr(
724+
attr, diag::ownership_modifier_unsupported_borrow_mutate_accessor,
725+
attr->getAttrName(),
726+
getAccessorNameForDiagnostic(accessor, /*article*/ true));
727+
}
728+
if (attrModifier == SelfAccessKind::Mutating &&
729+
accessor->isBorrowAccessor()) {
730+
diagnoseAndRemoveAttr(
731+
attr, diag::ownership_modifier_unsupported_borrow_mutate_accessor,
732+
attr->getAttrName(),
733+
getAccessorNameForDiagnostic(accessor, /*article*/ true));
734+
}
735+
}
711736
}
712737

713738
void AttributeChecker::visitDynamicAttr(DynamicAttr *attr) {

test/Sema/borrow_and_mutate_accessors.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@ class Klass {
99

1010
struct Struct {
1111
var _i: Int = 0
12+
var _k: Klass
13+
14+
var k1: Klass {
15+
consuming borrow { // expected-error{{a 'borrow' accessor cannot be declared consuming}}
16+
return _k
17+
}
18+
consuming mutate { // expected-error{{a 'mutate' accessor cannot be declared consuming}}
19+
return &_k
20+
}
21+
}
22+
23+
var k2: Klass {
24+
mutating borrow { // expected-error{{mutating ownership modifier is not yet supported on a 'borrow' accessor}}
25+
return _k
26+
}
27+
nonmutating mutate { // expected-error{{nonmutating ownership modifier is not yet supported on a 'mutate' accessor}}
28+
return &_k // expected-error{{'&' may only be used to pass an argument to inout parameter}}
29+
}
30+
}
31+
32+
var k3: Klass {
33+
nonmutating borrow {
34+
return _k
35+
}
36+
mutating mutate {
37+
return &_k
38+
}
39+
}
1240
}
1341

1442
extension Klass {

0 commit comments

Comments
 (0)