Skip to content

Commit e03cf1e

Browse files
committed
[Type Checker] Check subpattern storage instead of whole pattern.
Fixes SR-1050, where @NSManaged subpatterns were not yet visited, and thus still were deemed 'stored', by the time getStorage() was called on the whole pattern. Change this to check the subpattern storage as we go. Test case added.
1 parent 3b3914d commit e03cf1e

File tree

5 files changed

+20
-8
lines changed

5 files changed

+20
-8
lines changed

include/swift/AST/Pattern.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ class alignas(8) Pattern {
163163
});
164164
}
165165

166+
/// Does this binding declare something that requires storage?
167+
bool hasStorage() const;
168+
166169
static bool classof(const Pattern *P) { return true; }
167170

168171
//*** Allocation Routines ************************************************/

lib/AST/Decl.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,14 +1132,10 @@ StaticSpellingKind PatternBindingDecl::getCorrectStaticSpelling() const {
11321132
bool PatternBindingDecl::hasStorage() const {
11331133
// Walk the pattern, to check to see if any of the VarDecls included in it
11341134
// have storage.
1135-
bool HasStorage = false;
11361135
for (auto entry : getPatternList())
1137-
entry.getPattern()->forEachVariable([&](VarDecl *VD) {
1138-
if (VD->hasStorage())
1139-
HasStorage = true;
1140-
});
1141-
1142-
return HasStorage;
1136+
if (entry.getPattern()->hasStorage())
1137+
return true;
1138+
return false;
11431139
}
11441140

11451141
void PatternBindingDecl::setPattern(unsigned i, Pattern *P) {

lib/AST/Pattern.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ void Pattern::forEachNode(const std::function<void(Pattern*)> &f) {
237237
}
238238
}
239239

240+
bool Pattern::hasStorage() const {
241+
bool HasStorage = false;
242+
forEachVariable([&](VarDecl *VD) {
243+
if (VD->hasStorage())
244+
HasStorage = true;
245+
});
246+
247+
return HasStorage;
248+
}
249+
240250
/// Return true if this is a non-resolved ExprPattern which is syntactically
241251
/// irrefutable.
242252
static bool isIrrefutableExprPattern(const ExprPattern *EP) {

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2866,7 +2866,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
28662866
// default-initializable. If so, do it.
28672867
if (PBD->getPattern(i)->hasType() &&
28682868
!PBD->getInit(i) &&
2869-
PBD->hasStorage() &&
2869+
PBD->getPattern(i)->hasStorage() &&
28702870
!PBD->getPattern(i)->getType()->is<ErrorType>()) {
28712871

28722872
// If we have a type-adjusting attribute (like ownership), apply it now.

test/decl/var/NSManaged_properties.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class SwiftGizmo : A {
5050
@NSManaged func mutableArrayValueForB() {} // expected-error {{NSManaged method cannot have a body; it must be provided at runtime}}
5151
@NSManaged class func mutableArrayValueForA() {} // expected-error {{@NSManaged only allowed on an instance property or method}}
5252

53+
// SR-1050: don't assert
54+
@NSManaged var multiA, multiB, multiC : NSNumber?
55+
5356
override init() {}
5457
}
5558

0 commit comments

Comments
 (0)