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 @@ -1646,6 +1646,9 @@ class StorageRestrictionsAttr final
1646
1646
return {getTrailingObjects<Identifier>() + NumInitializes, NumAccesses};
1647
1647
}
1648
1648
1649
+ ArrayRef<VarDecl *> getInitializesProperties (AccessorDecl *attachedTo) const ;
1650
+ ArrayRef<VarDecl *> getAccessesProperties (AccessorDecl *attachedTo) const ;
1651
+
1649
1652
static StorageRestrictionsAttr *create (ASTContext &ctx, SourceLoc atLoc,
1650
1653
SourceRange range,
1651
1654
ArrayRef<Identifier> initializes,
Original file line number Diff line number Diff line change @@ -2608,6 +2608,26 @@ AccessesAttr::getPropertyDecls(AccessorDecl *attachedTo) const {
2608
2608
{});
2609
2609
}
2610
2610
2611
+ ArrayRef<VarDecl *> StorageRestrictionsAttr::getInitializesProperties (
2612
+ AccessorDecl *attachedTo) const {
2613
+ auto &ctx = attachedTo->getASTContext ();
2614
+ return evaluateOrDefault (ctx.evaluator ,
2615
+ InitAccessorReferencedVariablesRequest{
2616
+ const_cast <StorageRestrictionsAttr *>(this ),
2617
+ attachedTo, getInitializesNames ()},
2618
+ {});
2619
+ }
2620
+
2621
+ ArrayRef<VarDecl *>
2622
+ StorageRestrictionsAttr::getAccessesProperties (AccessorDecl *attachedTo) const {
2623
+ auto &ctx = attachedTo->getASTContext ();
2624
+ return evaluateOrDefault (ctx.evaluator ,
2625
+ InitAccessorReferencedVariablesRequest{
2626
+ const_cast <StorageRestrictionsAttr *>(this ),
2627
+ attachedTo, getAccessesNames ()},
2628
+ {});
2629
+ }
2630
+
2611
2631
void swift::simple_display (llvm::raw_ostream &out, const DeclAttribute *attr) {
2612
2632
if (attr)
2613
2633
attr->print (out);
Original file line number Diff line number Diff line change @@ -3591,6 +3591,21 @@ void AttributeChecker::visitAccessesAttr(AccessesAttr *attr) {
3591
3591
}
3592
3592
3593
3593
void AttributeChecker::visitStorageRestrictionsAttr (StorageRestrictionsAttr *attr) {
3594
+ auto *accessor = dyn_cast<AccessorDecl>(D);
3595
+ if (!accessor || accessor->getAccessorKind () != AccessorKind::Init) {
3596
+ diagnose (attr->getLocation (),
3597
+ diag::storage_restrictions_attribute_not_on_init_accessor);
3598
+ return ;
3599
+ }
3600
+
3601
+ auto initializesProperties = attr->getInitializesProperties (accessor);
3602
+ for (auto *property : attr->getAccessesProperties (accessor)) {
3603
+ if (llvm::is_contained (initializesProperties, property)) {
3604
+ diagnose (attr->getLocation (),
3605
+ diag::init_accessor_property_both_init_and_accessed,
3606
+ property->getName ());
3607
+ }
3608
+ }
3594
3609
}
3595
3610
3596
3611
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