Skip to content

Commit 554cce9

Browse files
authored
Merge pull request #65502 from DougGregor/accessor-macro-subsume-init-5.9
2 parents 19ef366 + f473bad commit 554cce9

File tree

11 files changed

+58
-18
lines changed

11 files changed

+58
-18
lines changed

include/swift/AST/Decl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5742,6 +5742,16 @@ class VarDecl : public AbstractStorageDecl {
57425742
return false;
57435743
}
57445744

5745+
/// Return the initializer that will initializer this VarDecl at runtime.
5746+
/// This is equivalent to `getParentInitializer()`, but returns `null` if the
5747+
/// initializer itself was subsumed, e.g., by a macro or property wrapper.
5748+
Expr *getParentExecutableInitializer() const;
5749+
5750+
/// Whether this variable has an initializer that will be code-generated.
5751+
bool isParentExecutabledInitialized() const {
5752+
return getParentExecutableInitializer() != nullptr;
5753+
}
5754+
57455755
// Return whether this VarDecl has an initial value, either by checking
57465756
// if it has an initializer in its parent pattern binding or if it has
57475757
// the @_hasInitialValue attribute.

lib/AST/Decl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6644,6 +6644,15 @@ bool VarDecl::isLazilyInitializedGlobal() const {
66446644
return !isTopLevelGlobal();
66456645
}
66466646

6647+
Expr *VarDecl::getParentExecutableInitializer() const {
6648+
if (auto *PBD = getParentPatternBinding()) {
6649+
const auto i = PBD->getPatternEntryIndexForVarDecl(this);
6650+
return PBD->getExecutableInit(i);
6651+
}
6652+
6653+
return nullptr;
6654+
}
6655+
66476656
SourceRange VarDecl::getSourceRange() const {
66486657
if (auto Param = dyn_cast<ParamDecl>(this))
66496658
return Param->getSourceRange();

lib/SILGen/SILGenConstructor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
401401
++elti;
402402
} else {
403403
assert(field->getType()->getReferenceStorageReferent()->isEqual(
404-
field->getParentInitializer()->getType()) &&
404+
field->getParentExecutableInitializer()->getType()) &&
405405
"Initialization of field with mismatched type!");
406406

407407
// Cleanup after this initialization.
@@ -422,7 +422,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
422422
}
423423
}
424424

425-
SGF.emitExprInto(field->getParentInitializer(), init.get());
425+
SGF.emitExprInto(field->getParentExecutableInitializer(), init.get());
426426
}
427427
if (SGF.getOptions().EnableImportPtrauthFieldFunctionPointers &&
428428
field->getPointerAuthQualifier().isPresent()) {
@@ -454,8 +454,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
454454
++elti;
455455
} else {
456456
// Otherwise, use its initializer.
457-
assert(field->isParentInitialized());
458-
Expr *init = field->getParentInitializer();
457+
assert(field->isParentExecutabledInitialized());
458+
Expr *init = field->getParentExecutableInitializer();
459459

460460
// If this is a property wrapper backing storage var that isn't
461461
// memberwise initialized, use the original wrapped value if it exists.

lib/SILGen/SILGenDecl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ class LetValueInitialization : public Initialization {
640640

641641
assert(!isa<ParamDecl>(vd)
642642
&& "should not bind function params on this path");
643-
if (vd->getParentPatternBinding() && !vd->getParentInitializer()) {
643+
if (vd->getParentPatternBinding() &&
644+
!vd->getParentExecutableInitializer()) {
644645
// If this is a let-value without an initializer, then we need a temporary
645646
// buffer. DI will make sure it is only assigned to once.
646647
needsTemporaryBuffer = true;
@@ -1427,8 +1428,8 @@ SILGenFunction::emitInitializationForVarDecl(VarDecl *vd, bool forceImmutable,
14271428
// If the variable has no initial value, emit a mark_uninitialized instruction
14281429
// so that DI tracks and enforces validity of it.
14291430
bool isUninitialized =
1430-
vd->getParentPatternBinding() && !vd->getParentInitializer();
1431-
1431+
vd->getParentPatternBinding() && !vd->getParentExecutableInitializer();
1432+
14321433
// If this is a global variable, initialize it without allocations or
14331434
// cleanups.
14341435
InitializationPtr Result;

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
13581358
StringRef(PropertyName));
13591359

13601360
if (auto *Var = dyn_cast<VarDecl>(VD)) {
1361-
if (Var->getParentInitializer())
1361+
if (Var->getParentExecutableInitializer())
13621362
diagnose(Module, SILLocation(VD),
13631363
diag::initial_value_provided_in_let_decl);
13641364
Var->emitLetToVarNoteIfSimple(nullptr);

lib/Sema/DebuggerTestingTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class DebuggerTestingTransform : public ASTWalker {
184184

185185
// Don't capture variables which aren't default-initialized.
186186
if (auto *VD = dyn_cast<VarDecl>(DstDecl))
187-
if (!VD->isParentInitialized() &&
187+
if (!VD->isParentExecutabledInitialized() &&
188188
!(isa<ParamDecl>(VD) &&
189189
cast<ParamDecl>(VD)->isInOut()))
190190
return Action::Continue(OriginalExpr);

lib/Sema/PCMacro.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ class Instrumenter : InstrumenterBase {
468468
if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
469469
// FIXME: Should iterate all var decls
470470
if (VarDecl *VD = PBD->getSingleVar()) {
471-
if (VD->getParentInitializer()) {
471+
if (VD->getParentExecutableInitializer()) {
472472

473473
SourceRange SR = PBD->getSourceRange();
474474
if (!SR.isValid()) {

lib/Sema/PlaygroundTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ class Instrumenter : InstrumenterBase {
581581
if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
582582
if (!PBD->isAsyncLet()) {
583583
if (VarDecl *VD = PBD->getSingleVar()) {
584-
if (VD->getParentInitializer()) {
584+
if (VD->getParentExecutableInitializer()) {
585585
Added<Stmt *> Log = logVarDecl(VD);
586586
if (*Log) {
587587
Elements.insert(Elements.begin() + (EI + 1), *Log);

lib/Sema/TypeCheckMacros.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,6 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
13111311
Optional<unsigned> swift::expandAccessors(
13121312
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
13131313
) {
1314-
(void)storage->getInterfaceType();
13151314
// Evaluate the macro.
13161315
auto macroSourceFile = evaluateAttachedMacro(macro, storage, attr,
13171316
/*passParentContext*/false,
@@ -1333,12 +1332,12 @@ Optional<unsigned> swift::expandAccessors(
13331332
if (accessor->isObservingAccessor())
13341333
continue;
13351334

1336-
// If any non-observing accessor was added, remove the initializer if
1337-
// there is one.
1335+
// If any non-observing accessor was added, mark the initializer as
1336+
// subsumed.
13381337
if (auto var = dyn_cast<VarDecl>(storage)) {
13391338
if (auto binding = var->getParentPatternBinding()) {
13401339
unsigned index = binding->getPatternEntryIndexForVarDecl(var);
1341-
binding->setInit(index, nullptr);
1340+
binding->setInitializerSubsumed(index);
13421341
break;
13431342
}
13441343
}

lib/Sema/TypeCheckStorage.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3292,10 +3292,10 @@ static void finishNSManagedImplInfo(VarDecl *var,
32923292
if (info.isSimpleStored()) {
32933293
// @NSManaged properties end up being computed; complain if there is
32943294
// an initializer.
3295-
if (var->getParentInitializer()) {
3295+
if (var->getParentExecutableInitializer()) {
32963296
auto &Diags = var->getASTContext().Diags;
32973297
Diags.diagnose(attr->getLocation(), diag::attr_NSManaged_initial_value)
3298-
.highlight(var->getParentInitializer()->getSourceRange());
3298+
.highlight(var->getParentExecutableInitializer()->getSourceRange());
32993299
}
33003300

33013301
// Otherwise, ok.
@@ -3312,13 +3312,22 @@ static void finishNSManagedImplInfo(VarDecl *var,
33123312
}
33133313
}
33143314

3315+
static Expr *getParentExecutableInitializer(VarDecl *var) {
3316+
if (auto *PBD = var->getParentPatternBinding()) {
3317+
const auto i = PBD->getPatternEntryIndexForVarDecl(var);
3318+
return PBD->getExecutableInit(i);
3319+
}
3320+
3321+
return nullptr;
3322+
}
3323+
33153324
static void finishStorageImplInfo(AbstractStorageDecl *storage,
33163325
StorageImplInfo &info) {
33173326
auto dc = storage->getDeclContext();
33183327

33193328
if (auto var = dyn_cast<VarDecl>(storage)) {
33203329
if (!info.hasStorage()) {
3321-
if (auto *init = var->getParentInitializer()) {
3330+
if (auto *init = var->getParentExecutableInitializer()) {
33223331
auto &Diags = var->getASTContext().Diags;
33233332
Diags.diagnose(init->getLoc(), diag::getset_init)
33243333
.highlight(init->getSourceRange());

test/stdlib/Observation/Observable.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ import StdlibUnittest
1010
import _Observation
1111
import _Concurrency
1212

13+
@available(SwiftStdlib 5.9, *)
14+
@MainActor @Observable
15+
final class StateMachine {
16+
enum State {
17+
case initializing
18+
case running
19+
case complete
20+
}
21+
22+
var state: State = .initializing
23+
}
24+
1325
@usableFromInline
1426
@inline(never)
1527
func _blackHole<T>(_ value: T) { }

0 commit comments

Comments
 (0)