Skip to content

Commit c926da1

Browse files
committed
[Sema] Adjust property wrapper mutability application
Only apply the relevant property wrapper mutability when we're performing an access via the wrapped value.
1 parent 5f17f5b commit c926da1

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,11 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
751751
bool isMemberLValue = isLValue;
752752
auto propertyWrapperMutability =
753753
[&](Decl *decl) -> Optional<std::pair<bool, bool>> {
754+
// If we're not accessing via a property wrapper, we don't need to adjust
755+
// the mutability.
756+
if (target != TargetImpl::Wrapper && target != TargetImpl::WrapperStorage)
757+
return None;
758+
754759
auto var = dyn_cast<VarDecl>(decl);
755760
if (!var)
756761
return None;

test/SILGen/property_wrappers.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,34 @@ struct ObservedObject<ObjectType : AnyObject > {
653653
}
654654
}
655655

656+
// SR-12443: Crash on property with wrapper override that adds observer.
657+
@propertyWrapper
658+
struct BasicIntWrapper {
659+
var wrappedValue: Int
660+
}
661+
662+
class Someclass {
663+
@BasicIntWrapper var property: Int = 0
664+
}
665+
666+
class Somesubclass : Someclass {
667+
override var property: Int {
668+
// Make sure we don't interact with the property wrapper, we just delegate
669+
// to the superclass' accessors.
670+
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers12SomesubclassC0A0Sivs : $@convention(method) (Int, @guaranteed Somesubclass) -> ()
671+
// CHECK: bb0([[NEW:%.+]] : $Int, {{%.+}} : @guaranteed $Somesubclass):
672+
// CHECK: [[GETTER:%.+]] = function_ref @$s17property_wrappers9SomeclassC0A0Sivg : $@convention(method) (@guaranteed Someclass) -> Int
673+
// CHECK: [[OLD:%.+]] = apply [[GETTER]]({{%.+}}) : $@convention(method) (@guaranteed Someclass) -> Int
674+
// CHECK: [[SETTER:%.+]] = function_ref @$s17property_wrappers9SomeclassC0A0Sivs : $@convention(method) (Int, @guaranteed Someclass) -> ()
675+
// CHECK: apply [[SETTER]]([[NEW]], {{%.+}}) : $@convention(method) (Int, @guaranteed Someclass) -> ()
676+
// CHECK: [[DIDSET:%.+]] = function_ref @$s17property_wrappers12SomesubclassC0A0SivW : $@convention(method) (Int, @guaranteed Somesubclass) -> ()
677+
// CHECK: apply [[DIDSET]]([[OLD]], {{%.+}}) : $@convention(method) (Int, @guaranteed Somesubclass) -> ()
678+
didSet {
679+
print("Subclass")
680+
}
681+
}
682+
}
683+
656684
// rdar://problem/58986940 - composition of wrappers with autoclosure
657685
@propertyWrapper
658686
struct Once<Value> {

0 commit comments

Comments
 (0)