Skip to content

Commit 27f86ad

Browse files
authored
Merge pull request #37627 from hborla/local-default-init-wrapper
[Property Wrappers] Always check actor isolation and initializer effects in `PropertyWrapperInitializerInfoRequest`.
2 parents cb319fc + aa8ad8e commit 27f86ad

File tree

4 files changed

+59
-30
lines changed

4 files changed

+59
-30
lines changed

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,31 +1867,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
18671867
});
18681868
}
18691869

1870-
/// If the given pattern binding has a property wrapper, check the
1871-
/// isolation and effects of the backing storage initializer.
1872-
void checkPropertyWrapperBackingInitializer(PatternBindingDecl *PBD) {
1873-
auto singleVar = PBD->getSingleVar();
1874-
if (!singleVar)
1875-
return;
1876-
1877-
if (!singleVar->hasAttachedPropertyWrapper())
1878-
return;
1879-
1880-
auto *backingVar = singleVar->getPropertyWrapperBackingProperty();
1881-
if (!backingVar)
1882-
return;
1883-
1884-
auto backingPBD = backingVar->getParentPatternBinding();
1885-
if (!backingPBD)
1886-
return;
1887-
1888-
auto initInfo = singleVar->getPropertyWrapperInitializerInfo();
1889-
if (auto initializer = initInfo.getInitFromWrappedValue()) {
1890-
checkPropertyWrapperActorIsolation(backingPBD, initializer);
1891-
TypeChecker::checkPropertyWrapperEffects(backingPBD, initializer);
1892-
}
1893-
}
1894-
18951870
void visitPatternBindingDecl(PatternBindingDecl *PBD) {
18961871
DeclContext *DC = PBD->getDeclContext();
18971872

@@ -2038,8 +2013,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20382013
}
20392014
}
20402015
}
2041-
2042-
checkPropertyWrapperBackingInitializer(PBD);
20432016
}
20442017

20452018
void visitSubscriptDecl(SubscriptDecl *SD) {

lib/Sema/TypeCheckStorage.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,6 +2584,11 @@ static void typeCheckSynthesizedWrapperInitializer(VarDecl *wrappedVar,
25842584
dyn_cast_or_null<Initializer>(parentPBD->getInitContext(i))) {
25852585
TypeChecker::contextualizeInitializer(initializerContext, initializer);
25862586
}
2587+
2588+
auto *backingVar = wrappedVar->getPropertyWrapperBackingProperty();
2589+
auto *backingPBD = backingVar->getParentPatternBinding();
2590+
checkPropertyWrapperActorIsolation(backingPBD, initializer);
2591+
TypeChecker::checkPropertyWrapperEffects(backingPBD, initializer);
25872592
}
25882593

25892594
static PropertyWrapperMutability::Value
@@ -2871,10 +2876,16 @@ PropertyWrapperInitializerInfoRequest::evaluate(Evaluator &evaluator,
28712876
if (!parentPBD->isInitialized(patternNumber) && wrapperInfo.defaultInit) {
28722877
// FIXME: Record this expression somewhere so that DI can perform the
28732878
// initialization itself.
2874-
Expr *initializer = nullptr;
2875-
typeCheckSynthesizedWrapperInitializer(var, initializer);
2876-
pbd->setInit(0, initializer);
2879+
Expr *defaultInit = nullptr;
2880+
typeCheckSynthesizedWrapperInitializer(var, defaultInit);
2881+
pbd->setInit(0, defaultInit);
28772882
pbd->setInitializerChecked(0);
2883+
2884+
// If a static, global, or local wrapped property has a default
2885+
// initializer, this is the only initializer that will be used.
2886+
if (var->isStatic() || !dc->isTypeContext()) {
2887+
initializer = defaultInit;
2888+
}
28782889
} else if (var->hasObservers() && !dc->isTypeContext()) {
28792890
var->diagnose(diag::observingprop_requires_initializer);
28802891
}

test/Concurrency/global_actor_inference.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,13 +361,22 @@ actor WrapperActorBad2<Wrapped> {
361361
}
362362
}
363363

364+
@propertyWrapper
365+
struct WrapperWithMainActorDefaultInit {
366+
var wrappedValue: Int { fatalError() }
367+
368+
@MainActor init() {} // expected-note {{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
369+
}
370+
364371
actor ActorWithWrapper {
365372
@WrapperOnActor var synced: Int = 0
366373
// expected-note@-1 3{{property declared here}}
367374
func f() {
368375
_ = synced // expected-error{{'synced' isolated to global actor}}
369376
_ = $synced // expected-error{{'$synced' isolated to global actor}}
370377
_ = _synced // expected-error{{'_synced' isolated to global actor}}
378+
379+
@WrapperWithMainActorDefaultInit var value: Int // expected-error {{call to main actor-isolated initializer 'init()' in a synchronous actor-isolated context}}
371380
}
372381
}
373382

test/SILGen/property_wrapper_local.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,39 @@ func testCaptures() {
190190
// closure #1 in testCaptures()
191191
// CHECK-LABEL: sil private [ossa] @$s22property_wrapper_local12testCapturesyyFyycfU_ : $@convention(thin) (@guaranteed { var Wrapper<Int> }) -> ()
192192
}
193+
194+
@propertyWrapper
195+
struct DefaultInit {
196+
var wrappedValue: Int
197+
198+
// CHECK-LABEL: sil hidden [ossa] @$s22property_wrapper_local11DefaultInitVACycfC : $@convention(method) (@thin DefaultInit.Type) -> DefaultInit
199+
init() {
200+
self.wrappedValue = 0
201+
}
202+
203+
// CHECK-LABEL: sil hidden [ossa] @$s22property_wrapper_local11DefaultInitV5valueACSi_tcfC : $@convention(method) (Int, @thin DefaultInit.Type) -> DefaultInit
204+
init(value: Int) {
205+
self.wrappedValue = value
206+
}
207+
}
208+
209+
@propertyWrapper
210+
struct DefaultWrappedValue {
211+
// CHECK-LABEL: sil hidden [ossa] @$s22property_wrapper_local19DefaultWrappedValueVACycfC : $@convention(method) (@thin DefaultWrappedValue.Type) -> DefaultWrappedValue
212+
var wrappedValue: Int = 10
213+
}
214+
215+
// CHECK-LABEL: sil hidden [ossa] @$s22property_wrapper_local20testLocalDefaultInityyF : $@convention(thin) () -> ()
216+
func testLocalDefaultInit() {
217+
// CHECK: function_ref @$s22property_wrapper_local11DefaultInitVACycfC : $@convention(method) (@thin DefaultInit.Type) -> DefaultInit
218+
@DefaultInit var x: Int
219+
220+
// CHECK: function_ref @$s22property_wrapper_local11DefaultInitV5valueACSi_tcfC : $@convention(method) (Int, @thin DefaultInit.Type) -> DefaultInit
221+
@DefaultInit(value: 10) var z: Int
222+
223+
// CHECK: function_ref @$s22property_wrapper_local11DefaultInitVACycfC : $@convention(method) (@thin DefaultInit.Type) -> DefaultInit
224+
@DefaultInit() var y: Int
225+
226+
// CHECK: function_ref @$s22property_wrapper_local19DefaultWrappedValueVACycfC : $@convention(method) (@thin DefaultWrappedValue.Type) -> DefaultWrappedValue
227+
@DefaultWrappedValue var w: Int
228+
}

0 commit comments

Comments
 (0)