Skip to content

Commit 3eaeafa

Browse files
authored
Merge pull request #65501 from DougGregor/accessor-macro-subsume-init
2 parents 2941051 + 593c236 commit 3eaeafa

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
@@ -6656,6 +6656,15 @@ bool VarDecl::isLazilyInitializedGlobal() const {
66566656
return !isTopLevelGlobal();
66576657
}
66586658

6659+
Expr *VarDecl::getParentExecutableInitializer() const {
6660+
if (auto *PBD = getParentPatternBinding()) {
6661+
const auto i = PBD->getPatternEntryIndexForVarDecl(this);
6662+
return PBD->getExecutableInit(i);
6663+
}
6664+
6665+
return nullptr;
6666+
}
6667+
66596668
SourceRange VarDecl::getSourceRange() const {
66606669
if (auto Param = dyn_cast<ParamDecl>(this))
66616670
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
@@ -646,7 +646,8 @@ class LetValueInitialization : public Initialization {
646646

647647
assert(!isa<ParamDecl>(vd)
648648
&& "should not bind function params on this path");
649-
if (vd->getParentPatternBinding() && !vd->getParentInitializer()) {
649+
if (vd->getParentPatternBinding() &&
650+
!vd->getParentExecutableInitializer()) {
650651
// If this is a let-value without an initializer, then we need a temporary
651652
// buffer. DI will make sure it is only assigned to once.
652653
needsTemporaryBuffer = true;
@@ -1433,8 +1434,8 @@ SILGenFunction::emitInitializationForVarDecl(VarDecl *vd, bool forceImmutable,
14331434
// If the variable has no initial value, emit a mark_uninitialized instruction
14341435
// so that DI tracks and enforces validity of it.
14351436
bool isUninitialized =
1436-
vd->getParentPatternBinding() && !vd->getParentInitializer();
1437-
1437+
vd->getParentPatternBinding() && !vd->getParentExecutableInitializer();
1438+
14381439
// If this is a global variable, initialize it without allocations or
14391440
// cleanups.
14401441
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
@@ -1303,7 +1303,6 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
13031303
Optional<unsigned> swift::expandAccessors(
13041304
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
13051305
) {
1306-
(void)storage->getInterfaceType();
13071306
// Evaluate the macro.
13081307
auto macroSourceFile = evaluateAttachedMacro(macro, storage, attr,
13091308
/*passParentContext*/false,
@@ -1325,12 +1324,12 @@ Optional<unsigned> swift::expandAccessors(
13251324
if (accessor->isObservingAccessor())
13261325
continue;
13271326

1328-
// If any non-observing accessor was added, remove the initializer if
1329-
// there is one.
1327+
// If any non-observing accessor was added, mark the initializer as
1328+
// subsumed.
13301329
if (auto var = dyn_cast<VarDecl>(storage)) {
13311330
if (auto binding = var->getParentPatternBinding()) {
13321331
unsigned index = binding->getPatternEntryIndexForVarDecl(var);
1333-
binding->setInit(index, nullptr);
1332+
binding->setInitializerSubsumed(index);
13341333
break;
13351334
}
13361335
}

lib/Sema/TypeCheckStorage.cpp

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

33023302
// Otherwise, ok.
@@ -3313,13 +3313,22 @@ static void finishNSManagedImplInfo(VarDecl *var,
33133313
}
33143314
}
33153315

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

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

test/stdlib/Observation/Observable.swift

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

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

0 commit comments

Comments
 (0)