Skip to content

Commit 641469e

Browse files
committed
Sema: Don't consider if 'didSet' references 'oldValue' when computing if setter is mutable
Previously this would depend on whether the 'didSet' referenced 'oldValue'. This introduces a request cycle once parse-time name lookup is disabled, and was also an ABI break from Swift 5.2. See https://forums.swift.org/t/clarify-behavior-of-se-0268-with-a-mutating-getter/40324.
1 parent 888dc92 commit 641469e

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,7 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
345345
if (auto *didSet = var->getParsedAccessor(AccessorKind::DidSet)) {
346346
// If there's a didSet, we call the getter for the 'oldValue', and so
347347
// should consider the getter's mutatingness as well
348-
if (!didSet->isSimpleDidSet()) {
349-
isMutating |= (mut->Getter == PropertyWrapperMutability::Mutating);
350-
}
348+
isMutating |= (mut->Getter == PropertyWrapperMutability::Mutating);
351349
isMutating |= didSet->getAttrs().hasAttribute<MutatingAttr>();
352350
}
353351
if (auto *willSet = var->getParsedAccessor(AccessorKind::WillSet))

test/SILGen/property_wrapper_observers.swift

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen -primary-file %s | %FileCheck %s
22

33
// 1. Make sure the wrapped property setter calls the observers
44
// 2. Make sure the synthesized _modify coroutine calls the wrapped property setter
@@ -108,3 +108,34 @@ struct MutatingWillSet {
108108
// CHECK-LABEL: sil private [ossa] @$s26property_wrapper_observers15MutatingWillSetV5value33_{{.*}}Sivs : $@convention(method) (Int, @inout MutatingWillSet) -> () {
109109
// CHECK: function_ref @$s26property_wrapper_observers15MutatingWillSetV5value33_{{.*}}Sivw : $@convention(method) (Int, @inout MutatingWillSet) -> ()
110110
// CHECK: function_ref @$s26property_wrapper_observers5StateV12wrappedValueSivs : $@convention(method) (Int, State) -> ()
111+
112+
@propertyWrapper struct MutatingGetter {
113+
var wrappedValue: Int {
114+
mutating get {
115+
return 3
116+
}
117+
nonmutating set {}
118+
}
119+
}
120+
121+
struct HasMutatingGetter {
122+
@MutatingGetter var hasDidSet: Int {
123+
didSet {}
124+
}
125+
126+
@MutatingGetter var hasWillSet: Int {
127+
willSet {}
128+
}
129+
}
130+
131+
// The didSet causes the setter to become mutating:
132+
133+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_observers17HasMutatingGetterV9hasDidSetSivg : $@convention(method) (@inout HasMutatingGetter) -> Int {
134+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_observers17HasMutatingGetterV9hasDidSetSivs : $@convention(method) (Int, @inout HasMutatingGetter) -> () {
135+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_observers17HasMutatingGetterV9hasDidSetSivM : $@yield_once @convention(method) (@inout HasMutatingGetter) -> @yields @inout Int {
136+
137+
// The willSet does not:
138+
139+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_observers17HasMutatingGetterV10hasWillSetSivg : $@convention(method) (@inout HasMutatingGetter) -> Int {
140+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_observers17HasMutatingGetterV10hasWillSetSivs : $@convention(method) (Int, HasMutatingGetter) -> () {
141+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_observers17HasMutatingGetterV10hasWillSetSivM : $@yield_once @convention(method) (@inout HasMutatingGetter) -> @yields @inout Int {

test/decl/var/property_wrappers.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,15 @@ struct UseWillSetDidSet {
446446
}
447447
}
448448

449+
struct DidSetUsesSelf {
450+
@Wrapper
451+
var x: Int {
452+
didSet {
453+
print(self)
454+
}
455+
}
456+
}
457+
449458
// ---------------------------------------------------------------------------
450459
// Mutating/nonmutating
451460
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)