File tree Expand file tree Collapse file tree 4 files changed +53
-0
lines changed Expand file tree Collapse file tree 4 files changed +53
-0
lines changed Original file line number Diff line number Diff line change @@ -1623,6 +1623,9 @@ class StorageRestrictionsAttr final
1623
1623
return {getTrailingObjects<Identifier>() + NumInitializes, NumAccesses};
1624
1624
}
1625
1625
1626
+ ArrayRef<VarDecl *> getInitializesProperties (AccessorDecl *attachedTo) const ;
1627
+ ArrayRef<VarDecl *> getAccessesProperties (AccessorDecl *attachedTo) const ;
1628
+
1626
1629
static StorageRestrictionsAttr *create (ASTContext &ctx, SourceLoc atLoc,
1627
1630
SourceRange range,
1628
1631
ArrayRef<Identifier> initializes,
Original file line number Diff line number Diff line change @@ -2596,6 +2596,26 @@ AccessesAttr::getPropertyDecls(AccessorDecl *attachedTo) const {
2596
2596
{});
2597
2597
}
2598
2598
2599
+ ArrayRef<VarDecl *> StorageRestrictionsAttr::getInitializesProperties (
2600
+ AccessorDecl *attachedTo) const {
2601
+ auto &ctx = attachedTo->getASTContext ();
2602
+ return evaluateOrDefault (ctx.evaluator ,
2603
+ InitAccessorReferencedVariablesRequest{
2604
+ const_cast <StorageRestrictionsAttr *>(this ),
2605
+ attachedTo, getInitializesNames ()},
2606
+ {});
2607
+ }
2608
+
2609
+ ArrayRef<VarDecl *>
2610
+ StorageRestrictionsAttr::getAccessesProperties (AccessorDecl *attachedTo) const {
2611
+ auto &ctx = attachedTo->getASTContext ();
2612
+ return evaluateOrDefault (ctx.evaluator ,
2613
+ InitAccessorReferencedVariablesRequest{
2614
+ const_cast <StorageRestrictionsAttr *>(this ),
2615
+ attachedTo, getAccessesNames ()},
2616
+ {});
2617
+ }
2618
+
2599
2619
void swift::simple_display (llvm::raw_ostream &out, const DeclAttribute *attr) {
2600
2620
if (attr)
2601
2621
attr->print (out);
Original file line number Diff line number Diff line change @@ -3553,6 +3553,21 @@ void AttributeChecker::visitAccessesAttr(AccessesAttr *attr) {
3553
3553
}
3554
3554
3555
3555
void AttributeChecker::visitStorageRestrictionsAttr (StorageRestrictionsAttr *attr) {
3556
+ auto *accessor = dyn_cast<AccessorDecl>(D);
3557
+ if (!accessor || accessor->getAccessorKind () != AccessorKind::Init) {
3558
+ diagnose (attr->getLocation (),
3559
+ diag::storage_restrictions_attribute_not_on_init_accessor);
3560
+ return ;
3561
+ }
3562
+
3563
+ auto initializesProperties = attr->getInitializesProperties (accessor);
3564
+ for (auto *property : attr->getAccessesProperties (accessor)) {
3565
+ if (llvm::is_contained (initializesProperties, property)) {
3566
+ diagnose (attr->getLocation (),
3567
+ diag::init_accessor_property_both_init_and_accessed,
3568
+ property->getName ());
3569
+ }
3570
+ }
3556
3571
}
3557
3572
3558
3573
void AttributeChecker::visitImplementsAttr (ImplementsAttr *attr) {
Original file line number Diff line number Diff line change 524
524
525
525
func test_invalid_storage_restrictions( ) {
526
526
struct Test {
527
+ var _a : Int
528
+ var _b : Int
529
+
527
530
var a : Int {
528
531
@storageRestrictions ( )
529
532
// expected-error@-1 {{missing label in @storageRestrictions attribute}}
@@ -553,5 +556,17 @@ func test_invalid_storage_restrictions() {
553
556
// expected-error@-1 {{unexpected label 'initialize' in @storageRestrictions attribute}}
554
557
init { }
555
558
}
559
+
560
+ var f : Int {
561
+ @storageRestrictions ( initializes: _a, accesses: _b, _a)
562
+ // expected-error@-1 {{property '_a' cannot be both initialized and accessed}}
563
+ init { }
564
+ }
565
+
566
+ var g : Int {
567
+ @storageRestrictions ( initializes: _a)
568
+ // expected-error@-1 {{@storageRestrictions attribute could only be used with init accessors}}
569
+ get { 0 }
570
+ }
556
571
}
557
572
}
You can’t perform that action at this time.
0 commit comments