Skip to content

Commit b2758ca

Browse files
authored
Merge pull request #25531 from DougGregor/property-wrappers-more-fixes-5.1
[5.1] Yet more minor fixes for property wrappers
2 parents 539c45f + 4fc7de3 commit b2758ca

File tree

3 files changed

+84
-4
lines changed

3 files changed

+84
-4
lines changed

lib/SILGen/RValue.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "Initialization.h"
2222
#include "SILGenFunction.h"
2323
#include "swift/AST/CanTypeVisitor.h"
24+
#include "swift/Basic/Defer.h"
2425
#include "swift/Basic/STLExtras.h"
2526
#include "swift/SIL/AbstractionPattern.h"
2627
#include "swift/SIL/SILArgument.h"
@@ -573,19 +574,19 @@ void RValue::assignInto(SILGenFunction &SGF, SILLocation loc,
573574

574575
ManagedValue RValue::getAsSingleValue(SILGenFunction &SGF, SILLocation loc) && {
575576
assert(!isUsed() && "r-value already used");
577+
SWIFT_DEFER {
578+
makeUsed();
579+
};
576580

577581
if (isInContext()) {
578-
makeUsed();
579582
return ManagedValue::forInContext();
580583
}
581584

582585
// Avoid killing and re-emitting the cleanup if the enclosed value isn't a
583586
// tuple.
584587
if (!isa<TupleType>(type)) {
585588
assert(values.size() == 1 && "exploded non-tuple?!");
586-
ManagedValue result = values[0];
587-
makeUsed();
588-
return result;
589+
return values[0];
589590
}
590591

591592
// *NOTE* Inside implodeTupleValues, we copy our values if they are not at +1.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,6 +1863,24 @@ static void validateSelfAccessKind(TypeChecker &TC, FuncDecl *FD) {
18631863
FD->setSelfAccessKind(SelfAccessKind::NonMutating);
18641864
else if (FD->getAttrs().hasAttribute<ConsumingAttr>())
18651865
FD->setSelfAccessKind(SelfAccessKind::__Consuming);
1866+
else if (auto accessor = dyn_cast<AccessorDecl>(FD)) {
1867+
if (accessor->getAccessorKind() == AccessorKind::Get ||
1868+
accessor->getAccessorKind() == AccessorKind::Set ||
1869+
accessor->getAccessorKind() == AccessorKind::DidSet ||
1870+
accessor->getAccessorKind() == AccessorKind::WillSet) {
1871+
auto storage = accessor->getStorage();
1872+
TC.validateDecl(storage);
1873+
if (accessor->getAccessorKind() == AccessorKind::Get) {
1874+
FD->setSelfAccessKind(storage->isGetterMutating()
1875+
? SelfAccessKind::Mutating
1876+
: SelfAccessKind::NonMutating);
1877+
} else {
1878+
FD->setSelfAccessKind(storage->isSetterMutating()
1879+
? SelfAccessKind::Mutating
1880+
: SelfAccessKind::NonMutating);
1881+
}
1882+
}
1883+
}
18661884

18671885
if (FD->isMutating()) {
18681886
if (!FD->isInstanceMember() ||

test/SILGen/property_wrappers.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,67 @@ func testComposition() {
346346
_ = CompositionMembers(p1: nil)
347347
}
348348

349+
// Observers with non-default mutatingness.
350+
@propertyWrapper
351+
struct NonMutatingSet<T> {
352+
private var fixed: T
353+
354+
var wrappedValue: T {
355+
get { fixed }
356+
nonmutating set { }
357+
}
358+
359+
init(initialValue: T) {
360+
fixed = initialValue
361+
}
362+
}
363+
364+
@propertyWrapper
365+
struct MutatingGet<T> {
366+
private var fixed: T
367+
368+
var wrappedValue: T {
369+
mutating get { fixed }
370+
set { }
371+
}
372+
373+
init(initialValue: T) {
374+
fixed = initialValue
375+
}
376+
}
377+
378+
struct ObservingTest {
379+
// ObservingTest.text.setter
380+
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers13ObservingTestV4textSSvs : $@convention(method) (@owned String, @guaranteed ObservingTest) -> ()
381+
// CHECK: function_ref @$s17property_wrappers14NonMutatingSetV12wrappedValuexvg
382+
@NonMutatingSet var text: String = "" {
383+
didSet { }
384+
}
385+
386+
@NonMutatingSet var integer: Int = 17 {
387+
willSet { }
388+
}
389+
390+
@MutatingGet var text2: String = "" {
391+
didSet { }
392+
}
393+
394+
@MutatingGet var integer2: Int = 17 {
395+
willSet { }
396+
}
397+
}
398+
399+
// Tuple initial values.
400+
struct WithTuples {
401+
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers10WithTuplesVACycfC : $@convention(method) (@thin WithTuples.Type) -> WithTuples {
402+
// CHECK: function_ref @$s17property_wrappers10WithTuplesV10$fractions33_F728088E0028E14D18C6A10CF68512E8LLAA07WrapperC12InitialValueVySd_S2dtGvpfi : $@convention(thin) () -> (Double, Double, Double)
403+
// CHECK: function_ref @$s17property_wrappers23WrapperWithInitialValueV07initialF0ACyxGx_tcfC : $@convention(method) <τ_0_0> (@in τ_0_0, @thin WrapperWithInitialValue<τ_0_0>.Type) -> @out WrapperWithInitialValue<τ_0_0>
404+
@WrapperWithInitialValue var fractions = (1.3, 0.7, 0.3)
405+
406+
static func getDefault() -> WithTuples {
407+
return .init()
408+
}
409+
}
349410

350411
// CHECK-LABEL: sil_vtable ClassUsingWrapper {
351412
// CHECK: #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg // ClassUsingWrapper.x.getter

0 commit comments

Comments
 (0)