Skip to content

Commit b6904d7

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 4183d97 commit b6904d7

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
@@ -166,6 +166,9 @@ class alignas(8) Pattern {
166166
});
167167
}
168168

169+
/// Does this binding declare something that requires storage?
170+
bool hasStorage() const;
171+
169172
static bool classof(const Pattern *P) { return true; }
170173

171174
//*** Allocation Routines ************************************************/

lib/AST/Decl.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -991,14 +991,10 @@ StaticSpellingKind PatternBindingDecl::getCorrectStaticSpelling() const {
991991
bool PatternBindingDecl::hasStorage() const {
992992
// Walk the pattern, to check to see if any of the VarDecls included in it
993993
// have storage.
994-
bool HasStorage = false;
995994
for (auto entry : getPatternList())
996-
entry.getPattern()->forEachVariable([&](VarDecl *VD) {
997-
if (VD->hasStorage())
998-
HasStorage = true;
999-
});
1000-
1001-
return HasStorage;
995+
if (entry.getPattern()->hasStorage())
996+
return true;
997+
return false;
1002998
}
1003999

10041000
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
@@ -3245,7 +3245,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
32453245
// default-initializable. If so, do it.
32463246
if (PBD->getPattern(i)->hasType() &&
32473247
!PBD->getInit(i) &&
3248-
PBD->hasStorage() &&
3248+
PBD->getPattern(i)->hasStorage() &&
32493249
!PBD->getPattern(i)->getType()->is<ErrorType>()) {
32503250

32513251
// 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
@@ -48,6 +48,9 @@ class SwiftGizmo : A {
4848
@NSManaged func mutableArrayValueForB() {} // expected-error {{NSManaged method cannot have a body; it must be provided at runtime}}
4949
@NSManaged class func mutableArrayValueForA() {} // expected-error {{@NSManaged only allowed on an instance property or method}}
5050

51+
// SR-1050: don't assert
52+
@NSManaged var multiA, multiB, multiC : NSNumber?
53+
5154
override init() {}
5255
}
5356

0 commit comments

Comments
 (0)