Skip to content

Commit 526a29f

Browse files
committed
[Sema] Prevent the initializer being double check by its backing storage.
1 parent e9f7e8d commit 526a29f

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

include/swift/AST/Decl.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,9 @@ class PatternBindingEntry {
15891589
/// Values captured by this initializer.
15901590
CaptureInfo Captures;
15911591

1592+
/// Whether the initializer is synthesized by type check.
1593+
bool IsSynthesized = false;
1594+
15921595
friend class Parser;
15931596
friend class PatternBindingInitializer;
15941597
friend class PatternBindingDecl;
@@ -1702,6 +1705,9 @@ class PatternBindingEntry {
17021705
PatternAndFlags.setInt(PatternAndFlags.getInt() | Flags::Subsumed);
17031706
}
17041707

1708+
bool isInitializerSynthesized() const { return IsSynthesized; }
1709+
void setInitializerSynthesized(bool value = true) { IsSynthesized = value; }
1710+
17051711
/// Returns \c true if the debugger created this pattern binding entry.
17061712
bool isFromDebugger() const {
17071713
return InitContextAndFlags.getInt().contains(PatternFlags::IsFromDebugger);
@@ -1942,7 +1948,15 @@ class PatternBindingDecl final : public Decl,
19421948
void setInitializerSubsumed(unsigned i) {
19431949
getMutablePatternList()[i].setInitializerSubsumed();
19441950
}
1945-
1951+
1952+
bool isInitializerSynthesized(unsigned i) const {
1953+
return getPatternList()[i].isInitializerSynthesized();
1954+
}
1955+
1956+
void setInitializerSynthesized(unsigned i) {
1957+
getMutablePatternList()[i].setInitializerSynthesized();
1958+
}
1959+
19461960
/// Does this binding declare something that requires storage?
19471961
bool hasStorage() const;
19481962

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,12 +2159,23 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
21592159
if (!DC->isLocalContext() &&
21602160
!(PBD->getSingleVar() &&
21612161
PBD->getSingleVar()->hasAttachedPropertyWrapper())) {
2162-
auto *initContext = cast_or_null<PatternBindingInitializer>(
2163-
PBD->getInitContext(i));
2162+
// Check whether `var` is a backing storage property and its
2163+
// initializer is already synthesized by storage check.
2164+
if (auto var = PBD->getSingleVar()) {
2165+
if (auto original = var->getOriginalWrappedProperty(
2166+
PropertyWrapperSynthesizedPropertyKind::Backing)) {
2167+
auto parentPBD = original->getParentPatternBinding();
2168+
if (parentPBD->isInitializerSynthesized(i))
2169+
continue;
2170+
}
2171+
}
2172+
auto *initContext =
2173+
cast_or_null<PatternBindingInitializer>(PBD->getInitContext(i));
21642174
if (initContext) {
21652175
TypeChecker::contextualizeInitializer(initContext, init);
21662176
checkInitializerActorIsolation(initContext, init);
21672177
TypeChecker::checkInitializerEffects(initContext, init);
2178+
PBD->setInitializerSynthesized(0);
21682179
}
21692180
}
21702181
}

lib/Sema/TypeCheckStorage.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2982,6 +2982,7 @@ PropertyWrapperInitializerInfoRequest::evaluate(Evaluator &evaluator,
29822982
typeCheckSynthesizedWrapperInitializer(var, defaultInit);
29832983
parentPBD->setInit(0, defaultInit);
29842984
parentPBD->setInitializerChecked(0);
2985+
parentPBD->setInitializerSynthesized(0);
29852986
}
29862987
}
29872988

@@ -3000,6 +3001,7 @@ PropertyWrapperInitializerInfoRequest::evaluate(Evaluator &evaluator,
30003001
typeCheckSynthesizedWrapperInitializer(var, defaultInit);
30013002
pbd->setInit(0, defaultInit);
30023003
pbd->setInitializerChecked(0);
3004+
pbd->setInitializerSynthesized(0);
30033005

30043006
// If a static, global, or local wrapped property has a default
30053007
// initializer, this is the only initializer that will be used.

test/Sema/property_wrapper_parameter.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,14 @@ func takesWrapperClosure<T>(_: ProjectionWrapper<[S<T>]>, closure: (ProjectionWr
137137
func testGenericPropertyWrapper<U>(@ProjectionWrapper wrappers: [S<U>]) {
138138
takesWrapperClosure($wrappers) { $wrapper in }
139139
}
140+
141+
@propertyWrapper
142+
public class SR_15940Bar<Value> {
143+
public init(wrappedValue: @autoclosure () -> Value) {}
144+
public var wrappedValue: Value {} // expected-error {{missing return in accessor expected to return 'Value'}}
145+
}
146+
147+
// SR-15940
148+
class SR_15940 {
149+
@SR_15940Bar var a: Bool?
150+
}

0 commit comments

Comments
 (0)