Skip to content

Commit fc895b4

Browse files
committed
[Sema] Formalize a way to check whether storage is initializable
Previously only stored properties could be initializable but with introduction of init accessors computed properties gained an ability to specify initialzer expression and participation in memberwise initialization for structs.
1 parent d1554f2 commit fc895b4

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5321,6 +5321,12 @@ class AbstractStorageDecl : public ValueDecl {
53215321
/// with it.
53225322
bool hasInitAccessor() const;
53235323

5324+
/// Return true if this is a property that either has storage
5325+
/// or init accessor associated with it.
5326+
bool supportsInitialization() const {
5327+
return hasStorage() || hasInitAccessor();
5328+
}
5329+
53245330
/// Return true if this storage has the basic accessors/capability
53255331
/// to be mutated. This is generally constant after the accessors are
53265332
/// installed by the parser/importer/whatever.

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2289,7 +2289,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
22892289
if (PBD->isInitialized(i)) {
22902290
// Add the attribute that preserves the "has an initializer" value
22912291
// across module generation, as required for TBDGen.
2292-
if (var->hasStorage() &&
2292+
if (var->supportsInitialization() &&
22932293
!var->getAttrs().hasAttribute<HasInitialValueAttr>()) {
22942294
var->getAttrs().add(new (Ctx)
22952295
HasInitialValueAttr(/*IsImplicit=*/true));

lib/Sema/TypeCheckMacros.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,9 +1319,11 @@ Optional<unsigned> swift::expandAccessors(
13191319
!accessorMacroOnlyIntroducesObservers(macro, roleAttr);
13201320
if (foundNonObservingAccessor) {
13211321
// If any non-observing accessor was added, mark the initializer as
1322-
// subsumed.
1322+
// subsumed unless it has init accessor, because the initializer in
1323+
// such cases could be used for memberwise initialization.
13231324
if (auto var = dyn_cast<VarDecl>(storage)) {
1324-
if (auto binding = var->getParentPatternBinding()) {
1325+
if (auto binding = var->getParentPatternBinding();
1326+
!var->getAccessor(AccessorKind::Init)) {
13251327
unsigned index = binding->getPatternEntryIndexForVarDecl(var);
13261328
binding->setInitializerSubsumed(index);
13271329
}

0 commit comments

Comments
 (0)